【问题标题】:Return value from website using scrapy使用scrapy从网站返回值
【发布时间】:2014-12-08 10:07:10
【问题描述】:

我在 Python 中使用 scrapy 试图从网站获取值,然后用于迭代。我遇到的问题是,似乎只能通过 yield 发送请求,这使得无法获得返回值。

class Spider(scrapy.Spider):

    name = 'spider'
    allowed_domains = ['domain.com']
    start_urls = ['url1', 'url2', ...]
    headers = ['id', 'name', 'description']
    pageNumber = 0 #tried to use a global variable but that doesn't really work because of the sub process.

    def start_requests(self):
        for su in self.start_urls:
            yield Request('http://url.com%s' % su,
                        self.parse_pageNumber)
            for i in range(pageNumber):
                page = su+str(pageNumber)
                yield Request('http://url.com' % page,
                    self.parse_matches)

    def parse_pageNumber(self, response):
        finds page number

    def.parse_matches(self, response):
        does everything else and returns items

知道如何在不做太多额外工作的情况下获取页码吗?

【问题讨论】:

  • 也许您想将产生页码请求的 for 循环放在 parse_pageNumber 中?
  • 那我就不知道哪个页码属于哪个页面了。关于无法访问该号码,我仍然会遇到同样的问题..

标签: python web-scraping scrapy yield


【解决方案1】:

正确的方法是使用meta 字典。首先,您创建初始请求以获取页码,但将感兴趣的 url 保留在 meta 字典中。然后在parse_pageNumber 中创建一个新请求,但这次将页码保留在meta 数据中。然后,您可以从 parse_matches 响应中检索页码。您可以这样做,因为 meta 是从 Request 浅复制到 Response 正是为了这个目的。您的代码可能如下所示:

class Spider(scrapy.Spider):

    name = 'spider'
    allowed_domains = ['domain.com']
    start_urls = ['url1', 'url2', ...]
    headers = ['id', 'name', 'description']

    def start_requests(self):
        for su in self.start_urls:
            yield Request('http://url.com%s' % su,
                        self.parse_pageNumber,
                        meta = {'su': su}
                          )

    def parse_pageNumber(self, response):
        pageNumber = response.xpath('get_page_number_expression')
        su = response.meta['su']
        for i in range(pageNumber):
                page = su + str(pageNumber)
                yield Request('http://url.com' % page,
                    self.parse_matches, meta={'page_number':str(pageNumber)})

    def parse_matches(self, response):
        pageNumber = response.meta['page_number']
        # do everything else

摘自official documentation以便更好地理解meta:

元
包含此请求的任意元数据的字典。对于新请求,此字典为空,通常由 不同的 Scrapy 组件(扩展、中间件等)。所以 此 dict 中包含的数据取决于您拥有的扩展名 启用。 有关特殊元键列表,请参阅 Request.meta 特殊键 被 Scrapy 识别。 当使用克隆请求时,这个字典是浅拷贝的 copy() 或 replace() 方法,也可以在您的蜘蛛中访问, 来自 response.meta 属性。

注意:
虽然建议使用meta 方法,但您的情况似乎更简单一些,因为您是通过直接使用页码来构造请求 URL,在这种情况下,您可能只使用urlparse 模块来在parse_matches() 方法中从response.url 中提取此信息。但是,meta 仍然是一种更强大的方法。

【讨论】:

  • 非常感谢。这正是我所需要的,并且您使我免于编写自己的过滤器来获取页码而无需刮擦。工作正常:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2016-01-01
  • 2013-05-09
  • 2018-08-04
  • 2020-10-12
  • 1970-01-01
相关资源
最近更新 更多