在Scrapy中,如何循环遍历几个自己抓取的start_urls

时间:2016-07-13 21:21:01

标签: python scrapy

我试图在http://www.funda.nl/koop/amsterdam/收集阿姆斯特丹待售房屋的数据。主页面只显示有限数量的房屋,底部有一个寻呼机,如下所示:

enter image description here

(" 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必须作为变量传递。

关于如何设置它的任何指示'?

1 个答案:

答案 0 :(得分:0)

这里的问题过于复杂 - 你不需要知道最大页面。

Scrapy有url dupefilter所以你可以使用linkextractor每次提取所有可见的页面,scrapy将足够智能,不会访问它们去过的页面,除非你强迫它。

所以你需要的是两个带有LinkExtractors的规则:一个提取所有链接并且回调为schedule(),一个提取所有可见页面并且没有回调或parse_item see docs here