Scrapy 在看似随机的点停止爬行
Scrapy stops crawling at seemingly random point
设置
我正在从 this site 抓取伦敦的房屋广告。
可以搜索 3 种不同区域大小的房屋广告:整个伦敦、特定区域(例如伦敦市中心)或特定分区(例如 Aldgate)。
该网站只允许您检查每个区域每 30 个广告的 50 个页面,无论区域大小。 IE。如果我 select 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
效果很好。
也就是说,它获得了指向的链接,
- 初始页面的区域
- 来自各个区域页面的子区域,每个区域
- 每个子区域页面的广告,遍历每个子区域的所有页面
最终从每个广告中抓取数据。
问题
代码似乎随机停止抓取,我不知道为什么。
我怀疑它已达到极限,因为它被告知要抓取许多链接和项目,但不确定我是否正确。
当它停止时,它指出,
{'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)}
我不确定是否有人可以从中读出我是否达到了限制或其他什么,但如果有人知道,请告诉我是否这样做以及如何防止代码停止。
尽管抓取过程的完整或至少部分日志将帮助您进行故障排除,但我会冒险 post 这个答案,因为我看到一件事;我假设是问题
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)
我很确定我知道发生了什么,运行 过去遇到过类似的问题并在您 运行 回调发送的最后一个函数的下一页时查看您的脚本它返回解析...其中我假设 link 到下一页是在那个实例 http 响应上...所以只需将回调更改为 parse_ad_overview ...
设置
我正在从 this site 抓取伦敦的房屋广告。
可以搜索 3 种不同区域大小的房屋广告:整个伦敦、特定区域(例如伦敦市中心)或特定分区(例如 Aldgate)。
该网站只允许您检查每个区域每 30 个广告的 50 个页面,无论区域大小。 IE。如果我 select 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
效果很好。
也就是说,它获得了指向的链接,
- 初始页面的区域
- 来自各个区域页面的子区域,每个区域
- 每个子区域页面的广告,遍历每个子区域的所有页面
最终从每个广告中抓取数据。
问题
代码似乎随机停止抓取,我不知道为什么。
我怀疑它已达到极限,因为它被告知要抓取许多链接和项目,但不确定我是否正确。
当它停止时,它指出,
{'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)}
我不确定是否有人可以从中读出我是否达到了限制或其他什么,但如果有人知道,请告诉我是否这样做以及如何防止代码停止。
尽管抓取过程的完整或至少部分日志将帮助您进行故障排除,但我会冒险 post 这个答案,因为我看到一件事;我假设是问题
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)
我很确定我知道发生了什么,运行 过去遇到过类似的问题并在您 运行 回调发送的最后一个函数的下一页时查看您的脚本它返回解析...其中我假设 link 到下一页是在那个实例 http 响应上...所以只需将回调更改为 parse_ad_overview ...