我试图在http://www.funda.nl/koop/amsterdam/收集阿姆斯特丹待售房屋的数据。主页面只显示有限数量的房屋,底部有一个寻呼机,如下所示:
(" Volgende"表示"下一个"荷兰语)。据此我推断总共有255页。这些网页中的每一个都有网址http://www.funda.nl/koop/amsterdam/p2/,http://www.funda.nl/koop/amsterdam/p3/,依此类推。为了获得所有房屋的数据,我想循环过来。所有子页面p1,p2,...,p255。
我试着看看我能做些什么来设置这个'。直到现在我已经写了以下代码:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from Funda.items import FundaItem
# from scrapy.shell import inspect_response
class FundaSpider(CrawlSpider):
name = "Funda"
allowed_domains = ["funda.nl"]
start_urls = ["http://www.funda.nl/koop/amsterdam/"]
le1 = LinkExtractor(allow=r'%s+huis-\d{8}' % start_urls[0]) # Link to the page of an individual house, such as http://www.funda.nl/koop/amsterdam/huis-49805292-nieuwendammerdijk-21/
le2 = LinkExtractor(allow=r'%s+p\d+' % start_urls[0]) # Link to a page containing thumbnails of several houses, such as http://www.funda.nl/koop/amsterdam/p10/
rules = (
Rule(le1, callback='parse_item'),
Rule(le2, callback='get_max_page_number')
)
def parse_item(self, response):
links = self.le1.extract_links(response)
for link in links:
if link.url.count('/') == 6 and link.url.endswith('/'):
item = FundaItem()
item['url'] = link.url
yield item
def get_max_page_number(self, response):
links = self.le2.extract_links(response)
max_page_number = 0
for link in links:
if link.url.count('/') == 6 and link.url.endswith('/'):
page_number = int(link.url.split("/")[-2].strip('p'))
if page_number > max_page_number:
max_page_number = page_number
return max_page_number
LinkExtractor le2
回拨get_max_page_number
,它只返回数字255.然后我想用这个数字来合成'不同的start_urls
适用于LinkExtractor le1
,它可以获取每个页面上各个房屋的链接。
问题在于,据我了解,scrapy
异步处理这些请求,因此我无法确保它首先获得数字255,然后使用该数字生成其他请求。如果是这样,我需要按顺序使用两个蜘蛛并从脚本中调用它们,而在第二个蜘蛛中,start_url
必须作为变量传递。
关于如何设置它的任何指示'?
答案 0 :(得分:0)
这里的问题过于复杂 - 你不需要知道最大页面。
Scrapy有url dupefilter所以你可以使用linkextractor每次提取所有可见的页面,scrapy将足够智能,不会访问它们去过的页面,除非你强迫它。
所以你需要的是两个带有LinkExtractors的规则:一个提取所有链接并且回调为schedule()
,一个提取所有可见页面并且没有回调或parse_item
see docs here