news 2026/3/4 7:39:43

Scrapy与Splash结合爬取JavaScript渲染页面

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scrapy与Splash结合爬取JavaScript渲染页面

在网络爬虫的开发过程中,我们经常会遇到一类 “棘手” 的目标网站 —— 基于 JavaScript 动态渲染的页面。这类网站不会在初始 HTML 中直接返回完整数据,而是通过前端脚本异步加载、渲染内容。传统的 Scrapy 爬虫直接解析响应文本,往往只能拿到空壳结构,无法获取有效信息。此时,将ScrapySplash结合,就成为了攻克这类网站的高效方案。

一、核心原理:为什么需要 Splash?

Scrapy 是 Python 生态中功能强大的爬虫框架,它以高效的异步请求、灵活的数据处理流程著称,但它的短板在于无法执行 JavaScript 代码。当爬虫向目标网站发送请求时,得到的响应是未经渲染的原始 HTML,其中动态加载的列表、数据、按钮等元素都尚未生成。

Splash 则是一个专门用于渲染 JavaScript 页面的轻量级工具,它本质是一个带有 HTTP API 的无界面浏览器,基于 Qt5 和 WebKit 内核。Splash 可以模拟真实浏览器的行为:加载页面、执行 JS 脚本、等待 DOM 渲染完成,然后返回渲染后的完整 HTML 页面,甚至可以截取页面截图、获取页面加载的 HAR 数据。

Scrapy 与 Splash 的结合逻辑非常清晰:

  1. Scrapy 不再直接向目标网站发送请求,而是将请求参数发送给 Splash 服务;
  2. Splash 接收请求后,模拟浏览器加载目标页面,完成 JS 渲染;
  3. Splash 将渲染后的 HTML 页面返回给 Scrapy;
  4. Scrapy 对渲染后的 HTML 进行解析,提取目标数据。

二、环境准备:安装与配置

在开始编写爬虫之前,我们需要完成基础环境的搭建,主要分为Splash 服务部署Python 依赖安装两步。

2.1 部署 Splash 服务

Splash 支持多种部署方式,最推荐的是Docker 容器部署,这种方式无需处理复杂的依赖关系,一键即可启动服务。

  1. 确保本地已安装 Docker 环境,执行以下命令拉取 Splash 镜像:

    bash

    运行

    docker pull scrapinghub/splash
  2. 启动 Splash 容器,映射端口(默认端口为 8050):

    bash

    运行

    docker run -p 8050:8050 scrapinghub/splash
  3. 验证服务是否启动成功:打开浏览器访问http://localhost:8050,若能看到 Splash 的测试页面,则说明部署成功。

2.2 安装 Python 依赖库

需要安装scrapy-splash库,它是 Scrapy 与 Splash 通信的桥梁,提供了专门的下载器中间件和请求类。

bash

运行

pip install scrapy-splash

三、Scrapy 项目配置:接入 Splash

创建一个新的 Scrapy 项目后,我们需要修改settings.py配置文件,让 Scrapy 能够使用 Splash 服务。

3.1 核心配置项

打开项目根目录下的settings.py,添加或修改以下配置:

python

运行

# 1. 配置Splash服务的地址 SPLASH_URL = 'http://localhost:8050' # 2. 启用Splash相关的下载器中间件 DOWNLOADER_MIDDLEWARES = { 'scrapy_splash.SplashCookiesMiddleware': 723, 'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810, } # 3. 配置Splash的去重过滤器 DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter' # 4. 配置缓存存储(可选,用于缓存Splash的响应) HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

这些配置的核心作用是让 Scrapy 的请求走 Splash 通道,并处理 Splash 响应的去重和缓存问题。

四、编写爬虫:实战爬取 JS 渲染页面

接下来,我们以一个简单的 JS 渲染页面为例,编写完整的爬虫代码。假设目标网站的动态数据是通过 Ajax 加载的商品列表,我们需要提取商品名称和价格。

4.1 创建爬虫文件

在项目的spiders目录下创建js_spider.py,代码如下:

python

运行

import scrapy from scrapy_splash import SplashRequest class JsRenderSpider(scrapy.Spider): name = 'js_render_spider' allowed_domains = ['example.com'] # 替换为目标域名 start_urls = ['https://example.com/js-render-page'] # 替换为目标URL # 定义Splash的Lua脚本:用于控制页面渲染过程 lua_script = """ function main(splash, args) -- 设置页面加载超时时间 splash:set_timeout(10) -- 加载目标页面 assert(splash:go(args.url)) -- 等待页面渲染完成(等待5秒,或等待指定元素出现) assert(splash:wait(5)) -- 返回渲染后的页面HTML return { html = splash:html(), -- 可选:返回页面截图 -- png = splash:png(), } end """ def start_requests(self): for url in self.start_urls: # 使用SplashRequest替代scrapy.Request yield SplashRequest( url=url, callback=self.parse, endpoint='execute', # 指定Splash的执行端点 args={ 'lua_source': self.lua_script, # 传入Lua脚本 'wait': 2 # 额外的等待参数 } ) def parse(self, response): # 解析渲染后的HTML(与普通Scrapy解析方式一致) products = response.xpath('//div[@class="product-item"]') for product in products: yield { 'name': product.xpath('.//h3/text()').get().strip(), 'price': product.xpath('.//span[@class="price"]/text()').get().strip() }

4.2 代码核心解析

  1. SplashRequest 替代 Request:这是与普通爬虫的核心区别,SplashRequest会将请求发送到 Splash 服务,并携带 Lua 脚本控制渲染流程。
  2. Lua 脚本的作用:Lua 脚本是 Splash 的灵魂,它可以实现复杂的页面操作:
    • splash:go(args.url):加载目标 URL;
    • splash:wait(5):等待 5 秒,确保 JS 脚本执行完毕、数据加载完成;
    • splash:html():获取渲染后的 HTML 源码;
    • 除此之外,还可以实现click(点击元素)、fill(填写表单)、scroll_position(滚动页面)等操作。
  3. 解析响应:经过 Splash 渲染后的响应,与普通 HTML 响应的解析方式完全一致,我们可以使用 XPath 或 CSS 选择器轻松提取数据。

五、高级技巧:优化渲染与爬取效率

在实际爬取过程中,我们需要根据目标网站的特性优化爬虫,避免出现超时、漏数据等问题。

5.1 智能等待:替代固定等待时间

固定的splash:wait(5)不够灵活,页面加载快时会浪费时间,加载慢时会导致渲染不完整。我们可以通过等待指定元素出现来优化:

lua

-- 等待class为"product-list"的元素出现,超时时间10秒 assert(splash:wait_for_element('div.product-list', 10))

5.2 处理动态加载的分页

对于无限滚动的分页页面,可以通过 Lua 脚本模拟滚动操作,触发更多数据加载:

lua

function main(splash, args) splash:go(args.url) splash:wait(2) -- 模拟向下滚动3次,每次滚动后等待2秒 for i=1,3 do splash:evaljs("window.scrollTo(0, document.body.scrollHeight)") splash:wait(2) end return splash:html() end

5.3 禁用图片加载:提升爬取速度

如果不需要页面截图,禁用图片、CSS 等资源的加载,可以大幅提升 Splash 的渲染速度:

lua

function main(splash, args) splash.images_enabled = false -- 禁用图片加载 splash:go(args.url) splash:wait(3) return splash:html() end

六、常见问题与解决方案

  1. Splash 服务连接失败

    • 检查 Docker 容器是否正常运行:docker ps
    • 确认SPLASH_URL配置正确,防火墙未拦截 8050 端口。
  2. 渲染后的页面仍无目标数据

    • 延长等待时间或使用wait_for_element等待关键元素;
    • 检查目标网站是否有反爬机制,可通过splash:set_user_agent()设置浏览器 UA。
  3. 爬虫效率过低

    • 禁用图片、CSS 加载;
    • 调整 Scrapy 的并发数(CONCURRENT_REQUESTS),避免 Splash 服务过载。

七、总结

Scrapy 与 Splash 的组合,完美解决了 JavaScript 渲染页面的爬取难题。Scrapy 负责请求调度、数据解析和持久化,Splash 负责模拟浏览器渲染,两者分工明确,极大拓展了爬虫的适用场景。在实际开发中,我们需要根据目标网站的特性编写灵活的 Lua 脚本,同时优化配置和爬取策略,才能在效率和稳定性之间找到最佳平衡点。

需要注意的是,爬虫开发应遵守目标网站的robots.txt协议,避免对服务器造成过大压力,做一个合规的开发者。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/4 4:48:41

Fun-ASR真实体验分享:会议录音转文字超高效

Fun-ASR真实体验分享:会议录音转文字超高效 在远程办公和线上协作日益普及的今天,会议记录已成为日常工作中不可或缺的一环。然而,手动整理录音不仅耗时耗力,还容易遗漏关键信息。有没有一种工具,能将会议录音快速、准…

作者头像 李华
网站建设 2026/2/25 0:04:32

Alkyne-PEG-Do;Alkyne-PEG-Dopamine:炔基 PEG 多巴胺的核心性能一览

试剂基本信息中文名称:丙炔聚乙二醇多巴胺;丙炔-聚乙二醇-多巴胺英文名称:Alkyne-PEG-Do;Dopamine-PEG-Alkyne;Alkyne-PEG-Dopamine外观:液体或固体粉末溶解性:溶于有机溶剂纯度:95%…

作者头像 李华
网站建设 2026/2/27 8:48:32

开箱即用!Docker快速部署Fun-ASR-MLT-Nano语音识别服务

开箱即用!Docker快速部署Fun-ASR-MLT-Nano语音识别服务 1. 项目背景与技术价值 1.1 多语言语音识别的工程挑战 在跨语言交互、智能客服、会议转录等场景中,多语言语音识别(Automatic Speech Recognition, ASR)已成为关键能力。…

作者头像 李华
网站建设 2026/3/4 1:49:29

.NET+AI | Workflow | 一文理清工作流核心概念(1)

MAF Workflow 核心概念详解📚 本课概览Microsoft Agent Framework (MAF) 提供了一套强大的 Workflow(工作流) 框架,用于编排和协调多个智能体(Agent)或处理组件的执行流程。本课将以通俗易懂的方式&#xf…

作者头像 李华
网站建设 2026/2/24 6:02:22

TensorFlow-v2.15实战教程:文本情感分析模型端到端部署

TensorFlow-v2.15实战教程:文本情感分析模型端到端部署 1. 引言与学习目标 随着自然语言处理技术的快速发展,文本情感分析已成为推荐系统、舆情监控和用户反馈分析中的关键能力。本文将基于 TensorFlow-v2.15 深度学习镜像环境,手把手带你完…

作者头像 李华
网站建设 2026/3/4 1:28:38

CubeMX生成安全互锁逻辑程序:工业控制核心要点

用CubeMX打造工业级安全互锁系统:从设计到落地的实战解析在自动化产线轰鸣运转的背后,有一道看不见的“数字护栏”默默守护着设备与人员的安全——这便是安全互锁逻辑。它不像算法优化那样炫技,也不像网络通信那样复杂,但它却是工…

作者头像 李华