返回博客
指南
Ștefan RăcilăLast updated on Mar 31, 20262 min read

Scrapy Splash 入门教程:掌握使用 Scrapy 和 Splash 抓取 JavaScript 渲染网站的技巧

Scrapy Splash 入门教程:掌握使用 Scrapy 和 Splash 抓取 JavaScript 渲染网站的技巧

在当今复杂的网络环境中,内容往往通过 JavaScript、AJAX 调用或其他客户端脚本动态生成,因此信息抓取成为了一项艰巨的任务。传统的抓取技术可能无法提取异步加载的数据,这需要更复杂的方法。这就是 Scrapy Splash 登场的时候了。

Scrapy Splash 是一款配备 HTTP API 的精简版浏览器。与臃肿的浏览器不同,它轻量却功能强大,专为抓取通过 JavaScript 或 AJAX 流程呈现内容的网站而设计。通过模拟真实浏览器的行为,Scrapy Splash 能够与动态元素进行交互,使其成为处理任何与 JavaScript 渲染内容相关的数据提取需求的宝贵工具。

在本全面指南中,我们将深入探讨 Scrapy Splash 的独特功能,并逐步演示如何有效利用该工具从使用 JavaScript 渲染的网站中抓取数据。无论您是经验丰富的数据挖掘者,还是初学者,了解 Scrapy Splash 的功能都将使您能够从日益动态化的网络中获取所需信息。

请继续关注,我们将深入探讨如何使用 Scrapy Splash 抓取现代交互式网页,内容涵盖从安装到实际案例的方方面面。

如何配置 Splash:安装与配置分步指南

Scrapy Splash 是一款功能极其强大的工具,能够为从动态网站抓取数据开辟新的可能性。然而,在开始享受 Scrapy Splash 带来的好处之前,我们必须先完成系统配置。这涉及几个关键步骤,包括安装 Docker、Splash、Scrapy,以及进行必要的配置以确保所有组件无缝协作。

1) 设置并安装 Docker

Docker 是一项前沿的容器化技术,它允许我们在虚拟容器中隔离并运行 Splash 实例,从而确保其平稳且一致的运行。

针对 Linux 用户:

在终端中执行以下命令:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

其他操作系统用户:

Windows、macOS 及其他操作系统用户可在 Docker 官网上找到详细的安装指南。

2) 通过 Docker 下载并安装 Splash

安装好 Docker 后,您可以继续下载 Splash Docker 镜像,这是我们爬虫基础设施的重要组成部分。

执行以下命令:

docker pull scrapinghub/splash

这将下载镜像。现在运行以下命令:

docker run -it -p 8050:8050 --rm scrapinghub/splash

恭喜!您的 Splash 实例现已就绪,可通过 localhost:8050 访问。在浏览器中访问此 URL 时,您应能看到默认的 Splash 页面。

3) 安装 Scrapy 及 Scrapy-Splash 插件

Scrapy 是一个灵活的爬取框架,而 scrapy-splash 插件则实现了 Scrapy 与 Splash 之间的连接。您可以通过以下命令同时安装这两者:

pip install scrapy scrapy-splash

上述命令将下载并安装所有必需的依赖项。

4) 创建您的第一个 Scrapy 项目

使用以下命令开启您的爬取之旅:

scrapy startproject splashscraper

这将创建一个名为 splashscraper 的 Scrapy 项目,其结构类似于:

splashscraper
├── scrapy.cfg
└── splashscraper
    ├── __init__.py
    ├── items.py
    ├── middlewares.py
    ├── pipelines.py
    ├── settings.py
    └── spiders
        └── __init__.py

5) 将 Scrapy 与 Splash 集成

现在到了关键步骤——配置 Scrapy 使其与 Splash 协同工作。这需要修改 Scrapy 项目中的 settings.py 文件。

Splash URL 配置:

为您的 Splash 实例定义一个变量:

SPLASH_URL = 'http://localhost:8050'

下载器中间件:

这些设置可实现与 Splash 的交互:

DOWNLOADER_MIDDLEWARES = {
   'scrapy_splash.SplashCookiesMiddleware': 723,
   'scrapy_splash.SplashMiddleware': 725,

}

Spider Middlewares and Duplicate Filters:
Further, include the necessary Splash middleware for deduplication:
SPIDER_MIDDLEWARES = {
   'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,

}

DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'

其余设置可保留默认值。

编写 Scrapy Splash 蜘蛛

从动态网页抓取数据可能需要与 JavaScript 进行交互。这就是 Scrapy Splash 发挥作用的地方。完成本指南后,您将学会如何使用 Scrapy Splash 创建一个蜘蛛,从 quotes.toscrape.com 抓取报价。

步骤 1:生成蜘蛛

我们将使用 Scrapy 的内置命令生成蜘蛛。命令如下:

scrapy genspider quotes quotes.toscrape.com

执行后,spiders 目录下将生成一个名为 quotes.py 的新文件。

步骤 2:了解 Scrapy 爬虫的基础知识

打开 quotes.py 文件,你会看到:

import scrapy

class QuotesSpider(scrapy.Spider):
   name = 'quotes'
   allowed_domains = ['quotes.toscrape.com']
   start_urls = ['http://quotes.toscrape.com/']
   def parse(self, response):
       pass
  • name:蜘蛛的名称
  • allowed_domains:将蜘蛛限制在列出的域名范围内
  • start_urls:待抓取的 URL
  • parse:针对每个 URL 调用的解析方法

步骤 3:从单个页面抓取数据

现在,让我们让蜘蛛正常运行。

a) 使用网页浏览器检查元素

使用开发者工具分析 HTML 结构。你会发现每条报价都被包含在一个类名为 quote 的 div 标签中。

b) 准备 SplashscraperItem 类

在 items.py 中进行修改,添加三个字段:author、text 和 tags:

import scrapy

class SplashscraperItem(scrapy.Item):
   author = scrapy.Field()
   text = scrapy.Field()
   tags = scrapy.Field()

c) 实现 parse() 方法

导入 SplashscraperItem 类,并更新 quotes.py 中的 parse 方法:

from items import SplashscraperItem

def parse(self, response):
   for quote in response.css("div.quote"):
       text = quote.css("span.text::text").extract_first("")
       author = quote.css("small.author::text").extract_first("")
       tags = quote.css("meta.keywords::attr(content)").extract_first("")
       item = SplashscraperItem()
       item['text'] = text
       item['author'] = author
       item['tags'] = tags
       yield item

步骤 4:处理分页

添加代码以遍历所有页面:

next_url = response.css("li.next>a::attr(href)").extract_first("")
if next_url:
    yield scrapy.Request(next_url, self.parse)

步骤 5:添加 SplashRequest 以获取动态内容

要使用 SplashRequest,您需要对当前的蜘蛛程序进行修改:

from scrapy_splash import SplashRequest

def start_requests(self):
   url = 'https://quotes.toscrape.com/'
   yield SplashRequest(url, self.parse, args={'wait': 1})

更新 parse 方法以使用 SplashRequest:

if next_url:
yield scrapy.SplashRequest(next_url, self.parse, args={'wait': 1})

恭喜!您刚刚编写了一个利用 Splash 抓取动态内容的、功能完整的 Scrapy 蜘蛛。现在您可以运行该蜘蛛,并从 quotes.toscrape.com 提取所有引文、作者和标签。

该代码为抓取其他结构相似的动态网站提供了绝佳的模板。祝您抓取愉快!

在 Scrapy 中处理 Splash 响应

Scrapy 中的 Splash 响应具有一些与标准 Scrapy 响应不同的独特特征。它们会根据响应类型以特定方式进行处理,但提取过程可以使用熟悉的 Scrapy 方法来完成。让我们深入探讨一下。

理解 Splash 如何响应请求及其响应对象

当 Scrapy Splash 处理请求时,会根据请求类型返回不同的响应子类:

  • SplashResponse:用于包含图像、视频、音频等媒体文件的二进制 Splash 响应。
  • SplashTextResponse:当结果为文本时。
  • SplashJsonResponse:当结果为 JSON 对象时。

解析 Splash 响应中的数据

可以使用 Scrapy 的内置解析器和 Selector 类来解析 Splash 响应。这意味着,尽管响应类型不同,但从中提取数据的方法保持不变。

以下是一个从 Splash 响应中提取数据的示例:

text = quote.css("span.text::text").extract_first("")
author = quote.css("small.author::text").extract_first("")
tags = quote.css("meta.keywords::attr(content)").extract_first("")

说明:

  • .css("span.text::text"): 此处使用 CSS 选择器定位类名为 text 的 span 元素,而 ::text 指示 Scrapy 从该元素中提取 text 属性。
  • .css("meta.keywords::attr(content)"): 此处使用 ::attr(content) 获取类名为 keywords 的 meta 标签的 content 属性。

结论

在 Scrapy 中处理 Splash 响应无需任何特殊处理。您仍可使用熟悉的方法和语法来提取数据。主要区别在于理解返回的 Splash 响应类型,它可能是标准文本、二进制或 JSON。这些类型可与常规 Scrapy 响应类似地处理,因此如果您将 Splash 添加到现有的 Scrapy 项目中,可以实现平滑过渡。

祝您使用 Splash 进行爬取愉快!

关于作者
Ștefan Răcilă, 全栈开发工程师 @ WebScrapingAPI
Ștefan Răcilă全栈开发工程师

Stefan Racila 是 WebScrapingAPI 的 DevOps 及全栈工程师,负责开发产品功能并维护确保平台稳定运行的基础设施。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。