如何使用Python Scrapy抓取单个页面的多个部分?

时间:2017-05-07 01:15:58

标签: python scrapy scrapy-spider

鉴于我有一个HTML文件,其中包含多个具有不同结构的部分,这些部分需要大量不同的抓取。 蜘蛛布局的最佳做法是什么?

我应该使用一只蜘蛛还是更多的蜘蛛?我应该多次请求相同的URL,每次都有不同的回调函数吗?或者只是顺序解析不同的部分?我要求能够与框架的其他部分一起玩得很好 - 比如 items pipleines - 以及明智的性能,限制和缓存。

那么,有什么最佳实践建议吗?社区中使用的规则或惯例?

多个请求

如果我多次请求URL,它是否被缓存/限制?或者对引擎的每个请求都会向外部Web服务器发出请求"?

class MultiSpider(scrapy.Spider):

    """Parse the parts in parallel."""

    name = 'multispider'

    def start_requests(self):
        url = 'https://en.wikipedia.org/wiki/Main_Page'
        yield scrapy.Request(url=url, callback=self.parser_01)
        yield scrapy.Request(url=url, callback=self.parser_02)

    def parser_01(self, response):
        selector = response.xpath('//some/path')
        if selector is not None:
            # do stuff with *selector* and
            yield {}

    def parser_0(self, response):
        selector = response.xpath('//some/other/path')
        if selector is not None:
            # do very different stuff with *selector* and
            yield {}

多个解析器函数

如果我想避免使用巨大的parse函数而是为不同的任务/部分使用多个函数,那么是否有特别好/坏的方法来构造它(例如"如何从哪里得到&#34 ;?)

class SeqSpider(scrapy.Spider):

    """Parse the page sequentially."""

    name = 'seqspider'

    start_urls = ['https://en.wikipedia.org/wiki/Main_Page', ]

    def parse(self, response):
        selector = response.xpath('//some/path')
        if selector:
            yield from self.parser_01(response, selector):
        selector = response.xpath('//some/other/path')
        if selector:
            yield from self.parser_02(response, selector):

    def parser_01(self, response, selector):
        # do stuff with *selector* and
        yield {}

    def parser_0(self, response, selector):
        # do very different stuff with *selector* and
        yield {}

1 个答案:

答案 0 :(得分:1)

如果是单页我会建议使用一只蜘蛛。请求页面一次并解析您需要的所有数据(您可以使用一个或多个函数)。

我还建议使用Items,例如

import scrapy

class AmazonItem(scrapy.Item):
    product_name = scrapy.Field()
    product_asin = scrapy.Field()
    product_avg_stars = scrapy.Field()
    product_num_reviews = scrapy.Field()
    pass

如果要将已爬网数据保存到数据库中,则应使用该管道。