Scrapy:谁能告诉我为什么这段代码不让我抓取后续页面?

问题描述

我是初学者,正在学习如何在 Python 中使用 Scrapy 进行网页抓取。有人能指出什么是错的吗?我的目标是抓取所有后续页面

from indeed.items import IndeedItem
import scrapy

class IndeedSpider(scrapy.Spider):
    name = "ind"
    allowed_domains = ["https://www.indeed.com"]
    start_urls = ['https://www.indeed.com/jobs?q=analytics+intern&start=']

    def parse(self,response):
        job_card = response.css('.jobsearch-SerpJobCard')
        for job in job_card:
            item = IndeedItem()

            job_title = job.css('.jobtitle::attr(title)').extract()
            company_name = job.css('.company .turnstileLink::text').extract()
            if not company_name:
                company_name = job.css('span.company::text').extract()

            item['job_title'] = job_title
            item['company_name'] = company_name
            yield item

        next_page_extension = response.css('ul.pagination-list a::attr(href)').get()
        if next_page_extension is not None:
            next_page = response.urljoin(next_page_extension)
            yield scrapy.Request(next_page,callback=self.parse)

解决方法

您的代码总体上看起来不错,但我发现它存在两个问题:

1 - allowed_domains 属性要求我们仅提供域,而不是完整的 URL。按原样运行它,您可能会在日志中看到如下内容:

2021-04-28 21:10:55 [scrapy.spidermiddlewares.offsite] DEBUG: Filtered offsite request to 'www.indeed.com': <GET https://www.indeed.com/jobs?q=analytics+intern&start=10>

这意味着 Scrapy 将忽略该请求,因为它不符合允许的域。要解决这个问题,只需使用:

allowed_domains = ["indeed.com"]

(more about it)

2 - 您用于分页的选择器将始终匹配分页小部件的第一个链接。您可以尝试改用 .getall(),或者将锚点标记为“Next”。例如:

next_page_extension = response.css(
    'ul.pagination-list a[aria-label=Next]::attr(href)'
).get()

,

该网站上的内容是使用 JavaScript 动态生成的。 Scrapy 单独不处理 JavaScript。您需要诸如 Selenium + ScrapySplash + ScrapyScrapy docs suggestother means 之类的东西。 Selenium 对初学者更友好,并且有很多关于如何将它与 Scrapy

一起使用的教程