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协议,避免对服务器造成过大压力,做一个合规的开发者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1165595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战演示:用麦橘超然Flux生成赛博朋克风城市街景

实战演示:用麦橘超然Flux生成赛博朋克风城市街景 1. 引言:AI图像生成的本地化实践新选择 随着生成式AI技术的快速发展,高质量图像生成已不再局限于云端服务。在边缘设备或本地环境中运行大模型成为越来越多开发者和创作者的需求。然而&…

Fun-ASR语音识别系统搭建:基于钉钉通义大模型的实操案例

Fun-ASR语音识别系统搭建:基于钉钉通义大模型的实操案例 1. 引言 随着语音交互技术在智能客服、会议记录、教育辅助等场景中的广泛应用,高精度、低延迟的语音识别系统成为企业数字化转型的重要工具。Fun-ASR 是由钉钉与通义实验室联合推出的语音识别大…

Qwen3-14B实战教程:从零开始部署企业级智能客服系统

Qwen3-14B实战教程:从零开始部署企业级智能客服系统 1. 引言 随着人工智能技术的快速发展,大型语言模型(LLM)在企业服务中的应用日益广泛。智能客服作为企业与用户交互的重要窗口,正逐步由规则驱动向AI驱动演进。Qwe…

GPT-OSS-20B-WEBUI参数调优:max_tokens与temperature设置建议

GPT-OSS-20B-WEBUI参数调优:max_tokens与temperature设置建议 1. 技术背景与应用场景 随着开源大模型生态的快速发展,OpenAI推出的GPT-OSS系列模型在社区中引发了广泛关注。其中,GPT-OSS-20B作为一款具备较强语言理解与生成能力的开源模型&…

5个必备翻译工具推荐:HY-MT1.5-1.8B镜像免配置上手

5个必备翻译工具推荐:HY-MT1.5-1.8B镜像免配置上手 1. 引言:轻量级多语翻译模型的工程突破 随着全球化内容消费和跨语言协作需求激增,高质量、低延迟、可本地部署的神经机器翻译(NMT)模型成为开发者与企业的刚需。然…

Qwen2.5-0.5B推理费用高?本地运行降本增效实战指南

Qwen2.5-0.5B推理费用高?本地运行降本增效实战指南 1. 背景与痛点:云上推理成本居高不下 随着大模型在各类业务场景中的广泛应用,推理服务的成本问题日益凸显。尤其是对于初创团队、个人开发者或边缘计算场景,依赖云端API调用的…

轻量翻译模型HY-MT1.5-1.8B:WMT25测试集表现分析

轻量翻译模型HY-MT1.5-1.8B:WMT25测试集表现分析 1. 引言 随着多语言交流需求的不断增长,神经机器翻译(NMT)已成为跨语言沟通的核心技术。然而,传统大模型在移动端部署面临显存占用高、推理延迟长等现实挑战。为解决…

Supertonic极速TTS实战:为技术类乐理博文注入声音

Supertonic极速TTS实战:为技术类乐理博文注入声音 1. 引言:当乐理遇上语音合成 在内容创作领域,文字依然是最主流的信息载体。然而,随着AI语音技术的发展,将静态文本转化为自然流畅的语音正成为提升阅读体验的重要手…

《创业之路》-859- 价值发现、价值实现、价值传递、价值回报是描述商业逻辑运行过程的动态流程,而商业模式画布是一种系统化表达商业模式的静态组成。

在商业模式分析中,价值发现、价值实现、价值传递、价值回报是描述商业逻辑运行过程的四个关键阶段,而商业模式画布(Business Model Canvas,即“9宫格”) 是一种系统化表达商业模式的工具。两者之间存在密切的对应关系&…

FSMN VAD API接口扩展:RESTful服务封装思路

FSMN VAD API接口扩展:RESTful服务封装思路 1. 背景与需求分析 1.1 FSMN VAD模型简介 FSMN VAD(Feedforward Sequential Memory Neural Network - Voice Activity Detection)是阿里达摩院在FunASR项目中开源的语音活动检测模型&#xff0c…

万物识别-中文-通用领域资源配置:最低显存要求实测报告

万物识别-中文-通用领域资源配置:最低显存要求实测报告 在当前多模态AI快速发展的背景下,图像理解能力已成为智能系统的核心组成部分。万物识别-中文-通用领域模型作为面向中文语境下图像内容理解的重要工具,具备对日常场景中各类物体、文字…

《创业之路》-860- 价值发现 → 客户细分 + 客户关系(初期) ↓ 价值实现 → 价值主张 + 关键业务 + 核心资源 + 重要合作 ↓ 价值传递 → 渠道通路 + 客户关系(维护) ↓ 价值回

映射关系价值发现 → 客户细分 客户关系(初期/探索)↓ 价值实现 → 价值主张 关键业务 核心资源 重要合作↓ 价值传递 → 渠道通路 客户关系(维护/留存)↓ 价值回报 → 收入来源 成本结构&#x1f…

cv_resnet18_ocr-detection省钱技巧:按需使用GPU降低部署成本

cv_resnet18_ocr-detection省钱技巧:按需使用GPU降低部署成本 1. 背景与问题分析 在OCR文字检测的实际部署中,模型推理性能和资源消耗是影响系统成本的关键因素。cv_resnet18_ocr-detection 是一个基于ResNet-18骨干网络的轻量级OCR检测模型&#xff0…

通义千问2.5-7B-Instruct本地运行:Mac M1芯片适配实战

通义千问2.5-7B-Instruct本地运行:Mac M1芯片适配实战 1. 背景与选型动机 随着大模型在开发者社区的普及,越来越多用户希望在本地设备上部署高性能、可商用的开源模型。对于 Mac 用户,尤其是搭载 M1/M2 系列芯片的设备,虽然具备…

亲测有效!VibeVoice-TTS网页端实现多人对话语音合成

亲测有效!VibeVoice-TTS网页端实现多人对话语音合成 1. 背景与需求:为什么需要多角色长时语音合成? 在播客、有声书、虚拟客服和AI角色对话等应用场景中,传统文本转语音(TTS)系统长期面临三大瓶颈&#x…

DCT-Net模型训练:小样本学习的实用技巧

DCT-Net模型训练:小样本学习的实用技巧 1. 引言 1.1 小样本学习在图像风格迁移中的挑战 在图像到图像翻译任务中,尤其是人像卡通化这类风格迁移应用,获取大量配对训练数据(如真实人像与对应卡通画)成本高昂且难以规…

JLink驱动安装方法:新手必看的Windows入门教程

手把手教你搞定JLink驱动安装:从踩坑到畅通无阻的Windows实战指南你有没有遇到过这样的场景?新买了一块STM32开发板,兴冲冲地连上J-Link调试器,结果设备管理器里只看到一个“未知设备”;或者Keil点了下载却提示“Canno…

Qwen新手教程:零基础云端部署,1小时1块轻松玩转

Qwen新手教程:零基础云端部署,1小时1块轻松玩转 你是不是也和我一样,做电商运营每天被“写文案”折磨得头大?商品标题要吸睛、详情页要走心、促销语还得有逼格——可灵感枯竭的时候,连“爆款推荐”都写得像白开水。最…

从部署到推理:PaddleOCR-VL-WEB实现本地图片与PDF精准识别

从部署到推理:PaddleOCR-VL-WEB实现本地图片与PDF精准识别 1. 引言:为何选择PaddleOCR-VL-WEB进行文档解析 在当前AI驱动的智能文档处理场景中,高效、准确且支持多语言的OCR系统成为企业与开发者的核心需求。尽管市场上已有多种OCR解决方案…

学Simulink--基础微电网场景实例:基于Simulink的直流微电网母线电压稳定控制仿真

目录 手把手教你学Simulink 一、引言:为什么直流微电网需要“母线电压稳定”? 二、系统整体架构 控制角色分配: 三、关键控制策略对比 1. 主从控制(Master-Slave) 2. 对等控制(Peer-to-Peer&#xff…