无法在网络抓取工具的类方法中使用会话

时间:2019-06-15 19:54:04

标签: python python-3.x class web-scraping

classmethod在网页中输入凭据后,我使用profilename创建了一个python脚本来提取loging in。该脚本能够以正确的方式获取profilename。我现在想做的是在session中使用classmethodsession已在__init__()方法中定义。 I would like to keep the existing design intact

这是我到目前为止尝试过的:

import requests
from bs4 import BeautifulSoup

class StackOverflow:

    SEARCH_URL = "https://stackoverflow.com/users/login?ssrc=head&returnurl=https%3a%2f%2fstackoverflow.com%2f"

    def __init__(self,session):
        self.session = session

    @classmethod
    def crawl(cls,email,password):
        page = requests.get(cls.SEARCH_URL,headers={"User-Agent":"Mozilla/5.0"})
        sauce = BeautifulSoup(page.text, "lxml")
        fkey = sauce.select_one("[name='fkey']")["value"]
        payload = {"fkey": fkey,"email": email,"password": password,}
        res = requests.post(cls.SEARCH_URL,data=payload,headers={"User-Agent":"Mozilla/5.0"})
        soup = BeautifulSoup(res.text, "lxml")
        user = soup.select_one("div[class^='gravatar-wrapper-']").get("title")
        yield user

if __name__ == '__main__':
    with requests.Session() as s:
        result = StackOverflow(s)
        for item in result.crawl("email", "password"):
            print(item)

如何在类方法中使用session中的__init__

1 个答案:

答案 0 :(得分:1)

您无法从类方法访问self.session。创建类的实例时将调用方法__init__,但是类方法并不绑定到该类的任何特定实例,而是绑定到类本身-这就是为什么第一个参数通常是cls而不是原因self

您决定在__init__中创建会话,因此可以假定

so1 = StackOverflow()
so2 = StackOverflow()

将他们的会话分开。如果确实是您的意图,则crawl方法不应使用@classmethod进行注释。如果您有crawl(self, email, pass):,则仍然可以使用StackOverflow.SEARCH_URLself.__class__.SEARCH_URL来获取StackOverflow类中定义的值,或者使用self.SEARCH_URL来默认获得相同的值,但可以使用so1.SEARCH_URL = "sth else"进行更改(但so2.SEARCH_URL会保留其原始值)