Scrapy 按照前面的链接

Scrapy follow previous links

我正在尝试使用从 url 'https://umanity.jp/en/racedata/race_6.php' 开始的 scrapy 跟踪前一年的链接。在这个url中,今年是2018年,有上一个按钮。当您单击该按钮时,它会转到 2017 年、2016 年……直到 2000 年。但是我写的 scrapy spider 在 2017 年停止了。我的代码:

import scrapy


class RaceSpider(scrapy.Spider):
    name = 'test'
    allowed_domains = ['umanity.jp']
    start_urls = ['https://umanity.jp/en/racedata/race_6.php']  # start to scrape from this url

    def parse(self, response):
        previous_year_btn = response.xpath('//div[@class="newslist_year_select m_bottom5"]/*[1]')
        if previous_year_btn.extract_first()[1] == 'a':
            href = previous_year_btn.xpath('./@href').extract_first()
            follow_link = response.urljoin(href)
            yield scrapy.Request(follow_link, self.parse_years)

    def parse_years(self, response):
        print(response.url)  # prints only year 2017

想不通为什么到2017年就停了,不去往年了。有什么问题?

您需要发送请求至self.parse;不是self.parse_years达到的效果。我试图从 xpaths 中剔除您的硬编码索引,以使其不易损坏。尝试以下方法:

class RaceSpider(scrapy.Spider):
    name = 'test'
    allowed_domains = ['umanity.jp']
    start_urls = ['https://umanity.jp/en/racedata/race_6.php']  # start to scrape from this url

    def parse(self, response):
        previous_year_btn = response.xpath('//div[contains(@class,"newslist_year_select")]/a')
        if 'race_prev.gif' in previous_year_btn.xpath('.//img/@src').extract_first():
            href = previous_year_btn.xpath('./@href').extract_first()
            yield scrapy.Request(response.urljoin(href), self.parse)
            print(response.url)

但是,保持第二种方法有效:

def parse(self, response):      
    yield scrapy.Request(response.url, self.parse_years)  #this is the fix

    previous_year_btn = response.xpath('//div[contains(@class,"newslist_year_select")]/a')
    if 'race_prev.gif' in previous_year_btn.xpath('.//img/@src').extract_first():
        href = previous_year_btn.xpath('./@href').extract_first()
        yield scrapy.Request(response.urljoin(href), self.parse)

def parse_years(self, response):
    print(response.url)

问题是 parse_years 函数没有进一步查找 link。

切换:
yield scrapy.Request(follow_link, self.parse_years)
yield scrapy.Request(follow_link, self.parse) 并找到所有年份,因为 parse 函数继续查找 links.

如果您确实想要两个单独的函数(也许 parse_years 对数据做某事,而 parse 找到下一个 link),这是可行的。

parse_years 只需要这个:

def parse_years(self, response):
    print(response.url)  # prints only year 2017
    yield from self.parse(response)