【问题标题】:Scrapy finishing process before all pages are scraped刮完所有页面之前的刮擦整理过程
【发布时间】:2020-10-22 19:59:51
【问题描述】:

我坐了一个测试 Scrapy 刮板,看起来像这样:

import scrapy

class testSpider(scrapy.Spider):
    name = 'test'
    start_urls = ['https://www.realestate.com.kh/buy/']

    def parse(self, response):
        nr_pages = response.xpath('//div[@class="desktop-buttons"]/a[@class="css-1en2dru"]//text()').getall()
        for nr in range(1, 40):
            req_url = f'?page={nr}'
            self.item = {}
            self.item['page'] = nr
            yield scrapy.Request(url=response.urljoin(req_url), callback=self.parse_page, meta={'item': self.item})

    def parse_page(self, response):
        page = response.meta['item']['page']
        ads = response.xpath('//*[@class="featured css-ineky e1jqslr40"]//a/@href')
        for url in ads:
            absolute_url = response.urljoin(url.extract())
            self.item = {}
            self.item['page'] = page
            yield scrapy.Request(absolute_url, callback=self.parse_ad, meta={'item': self.item})

    def parse_ad(self, response):
        page = response.meta['item']['page']
        # DO THINGS
        yield {
            'page': page
        }
  • 它会加载每个 https://www.realestate.com.kh/buy/?page=NR,其中 nr 是 1 到 40 之间的所有数字
  • 在每个页面上,它都会获得所有广告
  • 在每个页面的每个广告上,它都会抓取并生成内容。

前 26 个项目(两个首页,以及第 3 个项目中的 2 或 3 个项目,共 40 个)工作正常,然后完成抓取而没有错误。

以下是统计数据:

{'downloader/request_bytes': 23163,
 'downloader/request_count': 66,
 'downloader/request_method_count/GET': 66,
 'downloader/response_bytes': 3801022,
 'downloader/response_count': 66,
 'downloader/response_status_count/200': 66,
 'elapsed_time_seconds': 5.420036,
 'finish_reason': 'finished',
 'finish_time': datetime.datetime(2020, 10, 22, 19, 48, 37, 549853),
 'item_scraped_count': 26,
 'log_count/INFO': 9,
 'memusage/max': 49963008,
 'memusage/startup': 49963008,
 'request_depth_max': 2,
 'response_received_count': 66,
 'scheduler/dequeued': 66,
 'scheduler/dequeued/memory': 66,
 'scheduler/enqueued': 66,
 'scheduler/enqueued/memory': 66,
 'start_time': datetime.datetime(2020, 10, 22, 19, 48, 32, 129817)}

这么早结束抓取的原因是什么?

【问题讨论】:

    标签: scrapy


    【解决方案1】:

    您的蜘蛛实际上正在遍历所有页面,问题是在parse_pageads 的选择器仅在较早的页面中有效,在后面的页面中类名会更改。类名似乎是动态生成的,因此您需要一个不会按类选择的 XPath。

    此 XPath '//div/header/parent::div' 将返回与 '//*[@class="featured css-ineky e1jqslr40"]' 相同的 div 元素,因此替换此行应该允许您从所有页面中选择所有广告:

    ads = response.xpath('//div/header/parent::div/article/a/@href')
    

    无关说明: 这还没有导致任何问题,但它是未来问题的一个秘诀。

        for url in ads:
            absolute_url = response.urljoin(url.extract())
            self.item = {}
            self.item['page'] = page
            yield scrapy.Request(absolute_url, callback=self.parse_ad, meta={'item': self.item})
    

    Scrapy 以异步方式工作,因此大多数时候使用实例变量(如self.item)会给出错误的直觉,因为您无法真正控制解析请求的顺序。这就是为什么当您需要在使用meta(或cb_kwargs)而不只是将其存储在实例变量中的方法之间传递信息时。

    【讨论】:

      【解决方案2】:

      您正在以错误的方式获取页面,该网站目前有 50 个页面。您应该浏览下一页。看这段代码:

      import scrapy
      from scrapy.shell import inspect_response
      
      class testSpider(scrapy.Spider):
          name = 'test'
          start_urls = ['https://www.realestate.com.kh/buy/']
      
          def parse(self, response):
              page = response.xpath('//div[@class="list"]//div[@class="desktop-buttons"]/a[@class="css-owq2hj"]/span/text()').get()
              ads = response.xpath('//div[@class="list"]/div/header/a/@href').getall()
              for url in ads:
                  yield scrapy.Request(response.urljoin(url), callback=self.parse_ad, meta={'page': page})
              # next page
              url = response.xpath('//div[@class="list"]//div[@class="desktop-buttons"]/a[@class="css-owq2hj"]/following-sibling::a[1]/@href').get()
              if url:
                  yield scrapy.Request(response.urljoin(url), callback=self.parse)
      
          def parse_ad(self, response):
              page = response.meta['page']
              # DO THINGS
              yield {
                  'page': page
              }
      

      【讨论】:

      • 非常感谢您的帮助! @renatodvc 的答案对我有用,但我需要调查你的...
      猜你喜欢
      • 2018-04-18
      • 2014-02-05
      • 1970-01-01
      • 2018-05-22
      • 2019-09-28
      • 1970-01-01
      • 2012-11-08
      • 2022-01-02
      • 2020-01-09
      相关资源
      最近更新 更多