如何使用 Scrapy 爬取动态网站?

2023-04-17 00:00:00 scrapy 如何使用 动态网站

Scrapy 是 Python 网络爬虫框架,可以帮助我们轻松地从网站上提取数据。但是,当网站是动态的时候,Scrapy 的默认设置可能无法正确捕获数据。这时,我们需要使用其他技术,如 JavaScript 渲染和 AJAX 调用。

以下是使用 Scrapy 爬取动态网站的步骤:

  1. 分析网站

在开始爬取动态网站之前,我们需要先分析网站的结构和工作原理。通常,动态网站与静态网站最大的区别在于数据是通过 AJAX 调用获取的,而不是通过页面加载。因此,我们需要找到这些调用并模拟它们,以获取网站上的数据。

对于本例的 “pidancode.com”,我们可以在浏览器的开发者工具中查找 XHR 请求(Ajax 调用)。在请求头中包含 URL,我们可以使用此 URL 进行数据爬取。

  1. 创建 Scrapy 项目

在开始编写代码之前,我们需要创建 Scrapy 项目。使用以下命令:

$ scrapy startproject pdc_scrapy
  1. 编写爬虫

我们需要在 Scrapy 项目中创建 scrapy.Spider 子类,以定义我们的爬虫。下面是一个简单的示例:

# -*- coding: utf-8 -*-
import scrapy

class PdcSpider(scrapy.Spider):
    name = 'pdc'
    allowed_domains = ['pidancode.com']
    start_urls = ['https://www.pidancode.com/']

    def parse(self, response):
        pass

在上面的示例中,我们定义了一个名为“pdc”的爬虫,其只能访问“pidancode.com”域名下的页面。我们还定义了起始 URL,该 URL 用于启动爬虫并开始爬取动态网站。

  1. 使用 Splash 渲染页面

由于动态网站的页面是由 JavaScript 渲染的,所以我们需要使用一种方法来模拟此行为。 Splash 是一个渲染 JavaScript 的服务,可以与 Scrapy 集成以获取动态生成的页面。

在 Scrapy 项目中,我们可以使用 scrapy-splash 扩展来集成 Splash。使用以下命令安装:

$ pip install scrapy-splash

我们需要在 Scrapy 项目中的 settings.py 文件中启用扩展。添加以下 lines:

SPLASH_URL = 'http://localhost:8050'
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

这些行定义了使用 Splash 的默认设置。您还可以添加其他设置,以根据您的需求进行定制。

  1. 编写处理函数

处理函数是 Scrapy 爬虫中最重要的部分之一。在处理函数中,我们定义了如何提取我们需要的数据。 对于 “pidancode.com”,我们可以使用以下代码来提取标题和文章链接:

import scrapy

from scrapy_splash import SplashRequest

class PdcSpider(scrapy.Spider):
    name = 'pdc'
    allowed_domains = ['pidancode.com']
    start_urls = ['https://www.pidancode.com/']

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url, self.parse, args={'wait': 5})

    def parse(self, response):
        for post in response.css('.post'):
            yield {
                'title': post.css('.entry-title a::text').get(),
                'url': post.css('.entry-title a::attr(href)').get(),
            }

在以上代码中,我们首先使用 SplashRequest 代替默认的 Request,以在 Splash 的帮助下获取动态页面。 SplashRequest 使 Scrapy 调用 Splash 服务来呈现 JavaScript,然后返回呈现后的页面结果。

使用 response.css 和 response.xpath 方法来选择页面上我们需要的元素。在本例中,我们选择了 class 为“post”的所有元素,并从中提取标题和 URL。

  1. 运行爬虫

现在,我们已经准备好运行爬虫了。使用以下命令:

$ scrapy crawl pdc

在运行爬虫时,请确保启动 Splash 服务:

$ docker run -p 8050:8050 scrapinghub/splash

通过这种方式,我们就可以用 Scrapy 爬取动态网站了。

相关文章