Scrapy在看似随机的点上停止爬行

时间:2017-09-04 17:55:44

标签: python scrapy limit

设置向上

我正在从this site抓取伦敦住房广告。

可以搜索3种不同区域尺寸的住房广告:整个伦敦,特定区域(例如伦敦市中心)或特定分区(例如Aldgate)。

该网站只允许您检查每个区域每30个广告50页,无论区域大小。即如果我选择X,我可以在X中查看1500个广告,无论X是Central London还是Aldgate。

在撰写此问题时,网站上有超过37.000个广告。

由于我想尽可能多地抓取广告,这个限制意味着我需要在子区级别上抓广告。

为此,我写了以下蜘蛛,

# xpath to area/sub area links
area_links = ('''//*[@id="fullListings"]/div[1]/div/div/nav/aside/'''
          '''section[1]/div/ul/li/a/@href''')

class ApartmentSpider(scrapy.Spider):
    name = 'apartments2'
    start_urls = [
        "https://www.gumtree.com/property-to-rent/london"
        ]

    # obtain links to london areas
    def parse(self, response):                
            for url in response.xpath(area_links).extract():
                yield scrapy.Request(response.urljoin(url),
                         callback=self.parse_sub_area)    

    # obtain links to london sub areas
    def parse_sub_area(self, response):                
            for url in response.xpath(area_links).extract():
                yield scrapy.Request(response.urljoin(url),
                         callback=self.parse_ad_overview)    

    # obtain ads per sub area page
    def parse_ad_overview(self, response):                
            for ads in response.xpath('//*[@id="srp-results"]/div[1]/div/div[2]',
                                      ).css('ul').css('li').css('a',
                                           ).xpath('@href').extract():
                yield scrapy.Request(response.urljoin(ads),
                         callback=self.parse_ad)

                next_page = response.css(
            '#srp-results > div.grid-row > div > ul > li.pagination-next > a',
                                        ).xpath('@href').extract_first()
                if next_page is not None:
                    next_page = response.urljoin(next_page)
                    yield scrapy.Request(next_page, callback=self.parse) 

    # obtain info per ad
    def parse_ad(self, response):

    # here follows code to extract of data per ad

工作正常。

即,它获取指向

的链接
  1. 初始页面的区域
  2. 来自相应区域页面的子区域,每个区域
  3. 每个子区域页面展示广告,迭代每个子区域的所有页面
  4. 最终从每个广告中抓取数据。

    问题

    代码似乎随机停止抓取,我不知道为什么。

    我怀疑它已达到极限,因为它被告知刮掉许多链接和物品,但我不确定我是否正确。

    当它停止时,它说明,

    {'downloader/request_bytes': 1295950,
     'downloader/request_count': 972,
     'downloader/request_method_count/GET': 972,
     'downloader/response_bytes': 61697740,
     'downloader/response_count': 972,
     'downloader/response_status_count/200': 972,
     'dupefilter/filtered': 1806,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2017, 9, 4, 17, 13, 35, 53156),
     'item_scraped_count': 865,
     'log_count/DEBUG': 1839,
     'log_count/ERROR': 5,
     'log_count/INFO': 11,
     'request_depth_max': 2,
     'response_received_count': 972,
     'scheduler/dequeued': 971,
     'scheduler/dequeued/memory': 971,
     'scheduler/enqueued': 971,
     'scheduler/enqueued/memory': 971,
     'spider_exceptions/TypeError': 5,
     'start_time': datetime.datetime(2017, 9, 4, 17, 9, 56, 132388)}
    

    我不确定是否可以从中读到我是否已达到限制或某事,但如果有人知道,请告诉我,如果我这样做以及如何阻止代码停止。

1 个答案:

答案 0 :(得分:1)

虽然完整或至少部分的抓取过程日志可以帮助您排除故障,但我会冒险并发布此答案,因为我看到了一件事;我假设是问题

def parse_ad_overview(self, response):                
            for ads in response.xpath('//*[@id="srp-results"]/div[1]/div/div[2]',
                                      ).css('ul').css('li').css('a',
                                           ).xpath('@href').extract():
                yield scrapy.Request(response.urljoin(ads),
                         callback=self.parse_ad)

                next_page = response.css(
            '#srp-results > div.grid-row > div > ul > li.pagination-next > a',
                                        ).xpath('@href').extract_first()
                if next_page is not None:
                    next_page = response.urljoin(next_page)
                    yield scrapy.Request(next_page, callback=self.parse) 

我很确定我知道发生了什么,过去遇到了类似的问题,当你从最后一个函数运行你的下一页时,查看你的脚本,Callback将它发送回解析...其中我假设下一页的链接在该实例上http响应...所以只需将回调更改为parse_ad_overview ...