如何解析包含多个页面的项目?

时间:2018-02-17 22:37:06

标签: python scrapy

我有一个看起来像的网络蜘蛛:

def parse(self, response):
    links = LinkExtractor(unique=True).extract_links(response)
    for link in links:
        if '/item/' in link.url:
            yield response.follow(link, self.parse_item)
        else:
            yield response.follow(link, self.parse)

def parse_item(self, response):
    res = MyItem()
    res['Param1'] = response.xpath('_get_param_1')
    res['Param2'] = response.xpath('_get_param_2')
    res['Param3'] = response.xpath('_get_param_3')
    yield res

我的问题是每个项目在其他页面上都有其他信息,因此我需要修改我的代码:

def parse_item(self, response):
    res = MyItem()
    res['Param1'] = response.xpath('_get_param_1')
    res['Param2'] = response.xpath('_get_param_2')
    res['Param3'] = response.xpath('_get_param_3')

    new_url = response.url + '/more_info/'
    # Goto new_url
    res['Param4'] = response.xpath('_get_param_4')
    res['Param5'] = response.xpath('_get_param_5')

    yield res

但我不知道如何用干扰来做这件事。

UPD:我究竟需要什么。 我需要解析一个有不同公寓出租的网站。每个公寓都有site.com/item/id12345678这样的网址,此页面有priceaddress以及其他一些对我有用的信息,我可以像往常一样用scrappy解析它们但同样的公寓在第二页sellers_phone上添加了site.com/item/id12345678/more_info等其他信息。最后我想得到一个记录列表:

id, price, address, sellers_phone

2 个答案:

答案 0 :(得分:1)

这个问题非常大。 IIUC,你需要定义一个“旅程”,即访问几个网址,以收集一个公寓的所有潜在信息。您想使用scrapy,这是一个不错的选择。

以下是一种伪代码。不是为了工作,而是为了让您了解scrapy如何在您的案例中提供帮助。尽管有official documentation的强烈启发。我们的想法是使用callback参数来定义您想要做的下一步操作,一步一步(url by url)。

class MySpider(scrapy.Spider):

    start_urls = [
        "site.com/item/id12345678", 
        "site.com/item/id9786314", 
        ...]

    res = MyItem()

    def start_requests(self):
        for u in self.start_urls:
            yield scrapy.Request(u, 
                                 callback=self.parse_page_1)

    def parse_page_1(self, response):
        res['Param1'] = response.xpath('_get_param_1')
        res['Param2'] = response.xpath('_get_param_2')
        res['Param3'] = response.xpath('_get_param_3')
        yield scrapy.Request(url_more_info,  # call the page with more info
                            callback=self.parse_page_2)

    def parse_page_2(self, response):
        res['Param4'] = response.xpath('_get_param_4')
        res['Param5'] = response.xpath('_get_param_5')
        yield res

答案 1 :(得分:1)

为了以正确的方式汇总抓取的数据,我建议您使用Request.meta属性将值传递给请求。

来自official guide

  

在某些情况下,您可能有兴趣将参数传递给那些回调函数,以便稍后在第二个回调中接收参数。您可以使用Request.meta属性。

     

以下是如何使用此机制传递项目以填充不同页面中的不同字段的示例:

def parse_page1(self, response):
    item = MyItem()
    item['main_url'] = response.url
    request = scrapy.Request("http://www.example.com/some_page.html",
                             callback=self.parse_page2)
    request.meta['item'] = item
    yield request

def parse_page2(self, response):
    item = response.meta['item']
    item['other_url'] = response.url
    yield item

通过这种方式,即使在异步模式下,您也可以轻松地将外部页面与内部页面相关联,从而可以以正确的方式轻松导出结果。