首页 > 解决方案 > Scrapy实例方法神秘地拒绝调用另一个实例方法

问题描述

我正在使用 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):
    # ...

查看日志,到达“登录成功!” 部分,但永远不会“在 issue_requests() 内部”,并且由于生成器没有产生任何抓取的请求对象,所以下一步是关闭蜘蛛,什么都不做。

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

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

标签: pythonpython-2.7scrapycontrol-flow

解决方案


您还必须从中产生项目parse_login

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

推荐阅读