返回博客
指南
斯特凡·拉西拉2023年8月10日阅读时长:6分钟

Scrapy Splash 教程:掌握使用 Scrapy 和 Splash 抓取 JavaScript 渲染的网站的艺术

Scrapy Splash 教程:掌握使用 Scrapy 和 Splash 抓取 JavaScript 渲染的网站的艺术

如何配置 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。在浏览器中访问此网址时,您将看到默认的 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 网址配置:

为您的 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
  • 名称:蜘蛛的名字
  • 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 步:为动态内容添加 Splash 请求

要使用 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 选择器来定位具有 class 为 text 的 span 元素,而 ::text 则指示 Scrapy 从该元素中提取 text 属性。
  • .css("meta.keywords::attr(content)"): 这里,使用 ::attr(content) 来获取具有 class="keywords" 的 meta 标签的 content 属性。

结论

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

祝您使用 Splash 刮图愉快!

关于作者
Ștefan Răcilă,全栈开发者 @ WebScrapingAPI
斯特凡·拉西拉全栈开发工程师

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

开始构建

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

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