Python 剪贴式CSS选择器

Python 剪贴式CSS选择器,python,scrapy,Python,Scrapy,我正在学习如何使用刮痧,但我有一些问题。我在在线教程之后编写了这段代码,以进一步了解它 import scrapy class BrickSetSpider(scrapy.Spider): name = 'brick_spider' start_urls = ['http://brickset.com/sets/year-2016'] def parse(self, response): SET_SELECTOR = '.set' for brickset in respon

我正在学习如何使用刮痧,但我有一些问题。我在在线教程之后编写了这段代码,以进一步了解它

import scrapy

class BrickSetSpider(scrapy.Spider):
name = 'brick_spider'
start_urls = ['http://brickset.com/sets/year-2016']

def parse(self, response):
    SET_SELECTOR = '.set'
    for brickset in response.css(SET_SELECTOR):

        NAME_SELECTOR = 'h1 a ::text'
        PIECES_SELECTOR = './/dl[dt/text() = "Pieces"]/dd/a/text()'
        MINIFIGS_SELECTOR = './/dl[dt/text() = "Minifigs"]/dd[2]/a/text()'
        PRICE_SELECTOR  =  './/dl[dt/text() = "RRP"]/dd[3]/text()'
        IMAGE_SELECTOR = 'img ::attr(src)'
        yield {
            'name': brickset.css(NAME_SELECTOR).extract_first(),
            'pieces': brickset.xpath(PIECES_SELECTOR).extract_first(),
            'minifigs': brickset.xpath(MINIFIGS_SELECTOR).extract_first(),
    'retail price': brickset.xpath(PRICE_SELECTOR).extract_first(),
            'image': brickset.css(IMAGE_SELECTOR).extract_first(),
        }

    NEXT_PAGE_SELECTOR = '.next a ::attr(href)'
    next_page = response.css(NEXT_PAGE_SELECTOR).extract_first()
    if next_page:
        yield scrapy.Request(
            response.urljoin(next_page),
            callback=self.parse
        )
由于网站以年为单位划分产品,而此代码仅收集2016年的数据,因此我决定对其进行扩展,并分析前几年的数据。该准则的思想是:

PREVIOUS_YEAR_SELECTOR = '...'
previous_year= response.css(PREVIOUS_YEAR_SELECTOR).extract_first()
if previous_year:
    yield scrapy.Request(
        response.urljoin(previous_year),
                callback=self.parse
            )
我尝试了不同的东西,但我真的不知道该写什么来代替“…”
我也尝试使用xpath,但似乎没有任何效果。

也许您想利用
href
属性的结构?它似乎遵循结构
/sets/year YYYY
。通过这种方式,您可以使用基于正则表达式的选择器,或者-如果您像我一样懒惰-只使用
contains()

XPath:
//a[包含(@href,“/sets/year-”)/@href

我不确定CSS是否也能做到这一点。因此,
可以填充:

PREVIOUS_YEAR_SELECTOR_XPATH = '//a[contains(@href,"/sets/year-")]/@href'
previous_year = response.xpath(PREVIOUS_YEAR_SELECTOR).extract_first()
但我认为你会一直走下去,所以也许你想在链接上循环:

PREVIOUS_YEAR_SELECTOR_XPATH = '//a[contains(@href,"/sets/year-")]/@href'
for previous_year in response.xpath(PREVIOUS_YEAR_SELECTOR):
    yield scrapy.Request(response.urljoin(previous_year), callback=self.parse)

我认为你走得很好。谷歌搜索符合您需求的CSS/XPATH备忘单,并检查扩展或类似内容。它大大加快了选择器的设置速度:)

这里至少有两个选项。 第一种是使用泛型 并定义要提取和遵循的链接。 大概是这样的:

class BrickSetSpider(scrapy.CrawlSpider):
    name = 'brick_spider'
    start_urls = ['http://brickset.com/sets']
    rules = (
        Rule(LinkExtractor(
            allow=r'\/year\-[\d]{4}'), callback='parse_bricks', follow=True),
    )
#Your method renamed to parse_bricks goes here
注意:您需要将parse方法重命名为其他名称,如
'parse_bricks'
,因为爬行爬行器使用
parse
方法本身

第二个选项是将
start\u url
设置到包含所有年份集链接的页面,并添加解析这些链接的方法:

class BrickSetSpider(scrapy.Spider):
    name = 'brick_spider'
    start_urls = ['http://brickset.com/browse/sets']

    def parse(self, response):
        links = response.xpath(
            '//a[contains(@href, "/sets/year")]/@href').extract()
        for link in links:
            yield scrapy.Request(response.urljoin(link), callback=self.parse_bricks)

    # Your method renamed to parse_bricks goes here

谢谢你的回答!假设我只想找到前几年的数据,那么如果我写下你给我的第一个选项,它的工作方式应该与下一个页面选择器类似,对吗?问题是有许多链接包含/sets/year-,例如/sets/year-2015/page-3,我只需要打开其中一个,botton Scrapy会过滤掉重复的内容,所以不用担心。如果您只想在已知结构的有限数量的链接中爬行,那么可以用它填充
start\u url