【问题标题】:How to understand callback function in scrapy.Request?如何理解 scrapy.Request 中的回调函数?
【发布时间】:2020-07-04 17:06:03
【问题描述】:

我正在阅读 Web Scraping with Python 2nd Ed,并想使用 Scrapy 模块从网页中抓取信息。

我从文档中获得了以下信息:https://docs.scrapy.org/en/latest/topics/request-response.html

callback (callable) – 将被调用的函数 这个请求的响应(一旦它被下载)作为它的第一个 范围。有关详细信息,请参阅将附加数据传递给 下面的回调函数。如果请求未指定回调,则 将使用蜘蛛的 parse() 方法。请注意,如果有例外 在处理期间引发,而是调用 errback。

我的理解是:

  1. 传入 url 并像我们在 requests 模块中一样获得响应

    resp = requests.get(url)

  2. 传入resp进行数据解析

    解析(resp)

问题是:

  1. 我没有看到 resp 在哪里传入
  2. 为什么需要在参数解析前加上self关键字
  3. 在解析函数中从来没有使用self关键字,为什么要把它作为第一个参数?
  4. 我们可以像这样从响应参数中提取 url:url = response.url 还是应该是 url = self.url
class ArticleSpider(scrapy.Spider):
    name='article'
    
    def start_requests(self):
        urls = [
        'http://en.wikipedia.org/wiki/Python_'
        '%28programming_language%29',
        'https://en.wikipedia.org/wiki/Functional_programming',
        'https://en.wikipedia.org/wiki/Monty_Python']

        return [scrapy.Request(url=url, callback=self.parse) for url in urls]
    

    def parse(self, response):
        url = response.url
        title = response.css('h1::text').extract_first()
        print('URL is: {}'.format(url))
        print('Title is: {}'.format(title))

【问题讨论】:

  • scrapy 使用异步并被构建用作生成器(始终使用yield),约定是在其处理response的任何函数中传递self, response

标签: python callback scrapy


【解决方案1】:

您似乎缺少一些与 python 类和 OOP 相关的概念。阅读 python docs 或至少 this question 是一个好主意。

以下是 Scrapy 的工作方式,您实例化一个请求对象并将其交给 Scrapy 调度程序。

yield scrapy.Request(url=url) #or use return like you did

Scrapy 将处理请求,下载 html,并将它收到的所有请求返回给回调函数。如果您没有在请求中设置回调函数(如我上面的示例),它将调用名为 parse 的默认函数。

Parse 是对象的一种方法(也称为函数)。你在上面的代码中编写了它,即使你没有它仍然存在,因为你的类继承了它的父类的所有函数

class ArticleSpider(scrapy.Spider): # <<<<<<<< here
    name='article'

所以一个 TL;回答您的问题:

1-你没有看到它,因为它发生在父类中。

2-您需要使用self.,以便python知道您正在引用蜘蛛实例的方法。

3-self参数是它self的实例,被python使用了。

4-Response 是您的 parse 方法作为参数接收的独立对象,因此您可以访问它的属性,例如 response.urlresponse.headers

【讨论】:

  • 其实你可以跳过约定parse,只使用staticmethod(甚至普通函数)来处理响应
  • 嗨 renatodvc,我很困惑的是为什么我们可以从 response.url 中获取 url,因为我没有看到任何地方明确传入了这个参数。
【解决方案2】:

您可以在这里找到有关self 的信息 - https://docs.python.org/3/tutorial/classes.html


关于这个问题:

can we extract URL from response parameter like this: url = response.url or should be url = self.url

您应该使用response.url 来获取您当前抓取/解析的页面的 URL

【讨论】:

  • 您好 Roman,感谢您的反馈,您明白了我的意思。我要问的是为什么我们可以从 response.url 中获取 url,因为我没有看到在任何地方明确传入了这个参数。
猜你喜欢
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多