【问题标题】:Scrapy instance method mysteriously refusing to call another instance methodScrapy实例方法神秘地拒绝调用另一个实例方法
【发布时间】:2021-07-19 23:00:50
【问题描述】:

我正在使用 Scrapy 抓取一个网站,该网站有一个登录页面,后跟一组具有连续整数 ID 的内容页面,作为 URL 参数提取。这已经成功运行了一段时间,但是前几天我决定将产生请求的代码移动到一个单独的方法中,这样我就可以在初始加载之外的其他地方调用它(基本上是动态添加更多页面到获取)。

而且它... 只是不会调用那个单独的方法。它到达了我调用self.issue_requests() 的位置,并继续执行它,就好像指令不存在一样。

所以这个(蜘蛛类定义的一部分,没有单独的方法)有效:

    # ...final bit of start_requests():
    yield scrapy.FormRequest(url=LOGIN_URL + '/login', method='POST', formdata=LOGIN_PARAMS, callback=self.parse_login)

def parse_login(self, response):
    self.logger.debug("Logged in successfully!")
    global next_priority, input_reqno, REQUEST_RANGE, badreqs

    # go through our desired page numbers
    while len(REQUEST_RANGE) > 0:
        input_reqno = int(REQUEST_RANGE.pop(0))

        if input_reqno not in badreqs:
            yield scrapy.Request(url=REQUEST_BASE_URL + str(input_reqno), method='GET', meta={'input_reqno': input_reqno,'dont_retry': True}, callback=self.parse_page, priority = next_priority)
            next_priority -= 1

def parse_page(self, response):
    # ...

...但是,这种轻微的重构不会:

    # ...final bit of start_requests():
    yield scrapy.FormRequest(url=LOGIN_URL + '/login', method='POST', formdata=LOGIN_PARAMS, callback=self.parse_login)

def issue_requests(self):
    self.logger.debug("Inside issue_requests()!")
    global next_priority, input_reqno, REQUEST_RANGE, badreqs

    # go through our desired page numbers
    while len(REQUEST_RANGE) > 0:
        input_reqno = int(REQUEST_RANGE.pop(0))

        if input_reqno not in badreqs:
            yield scrapy.Request(url=REQUEST_BASE_URL + str(input_reqno), method='GET', meta={'input_reqno': input_reqno,'dont_retry': True}, callback=self.parse_page, priority = next_priority)
            next_priority -= 1
    return

def parse_login(self, response):
    self.logger.debug("Logged in successfully!")
    self.issue_requests()

def parse_page(self, response):
    # ...

查看日志,到达“登录成功!”部分,但是永远得到“inside issue_requests()”,并且由于生成器没有产生scrapy Request对象,它的下一步是关闭蜘蛛,什么都不做。

我从未见过对象实例拒绝调用方法的情况。如果它无法将控制权传递给方法,或者如果方法中的变量范围存在(比如说)问题,您会期望出现一些失败消息。但它默默地继续前进并假装我从未告诉它去issue_requests(),对我来说,这很奇怪。救命!

(这是 Python 2.7.18,顺便说一句)

【问题讨论】:

  • issue_requests() 是一个 generator - 仅仅调用它并不会执行其中的任何代码,您必须遍历它的返回值才能做到这一点。
  • 它在 while 循环内,因此每个调用都应该生成一堆请求,就像循环在 parse_login() 的一部分时所做的一样,不是吗?在“pre”示例中运行时,它会清空可能有数千个条目的 REQUEST_RANGE,并为每个条目生成一个请求。

标签: python python-2.7 scrapy control-flow


【解决方案1】:

您还必须从 parse_login 产生项目:

def parse_login(self, response):
    self.logger.debug("Logged in successfully!")
    for req in self.issue_requests():
        yield req

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2020-10-15
    • 2011-12-30
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多