首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
12.1 Charles 抓包工具的使用
12.2 mitmproxy 抓包工具的使用
12.3 mitmdump 实时抓包处理
12.4 Appium 的使用
12.5 基于 Appium 的 App 爬取实战
12.6 Airtest 的使用
12.7 基于 Airtest 的 App 爬取实战
12.8 手机群控爬取实战
12.9 云手机的使用
13.0 Android 逆向
13.1 jadx 的使用
13.2 JEB 的使用
13.3 Xposed 框架的使用
13.4 基于 Xposed 的爬取实战案例
13.5 Frida 的使用
13.6 SSL Pining 问题的解决方案
13.7 Android 脱壳技术简介与实战
13.8 利用 IDA Pro 静态分析和动态调试 so 文件
13.9 基于 Frida-RPC 模拟执行 so 文件
13.10 基于 AndServer-RPC 模拟执行 so 文件
13.11 基于 unidbg 模拟执行 so 文件
14.1 页面智能解析简介
14.2 详情页智能解析算法简介
14.3 详情页智能解析算法的实现
14.4 列表页智能解析算法简介
14.5 列表页智能解析算法的实现
14.6 如何智能分辨列表页和详情页
15.1 Scrapy框架介绍
15.2 Scrapy入门
15.3 Selector 的使用
15.4 Spider 的使用
15.5 Downloader Middleware的使用
15.6 Spider Middleware的使用
15.7 Item Pipeline的使用
15.8 Extension的使用
15.9 Scrapy 对接 Selenium
15.10 Scrapy 对接 Splash
15.11 Scrapy 对接 Pyppeteer
15.12 Scrapy 规则化爬虫
15.13 Scrapy 实战
16.1 分布式爬虫理念
16.2 Scrapy-Redis原理和源码解析
16.3 基于Scrapy-Redis的分布式爬虫实现
16.4 基于Bloom Filter进行大规模去重
16.5 基于RabbitMQ的分布式爬虫
17.1 Scrapyd和ScrapydAPI的使用
17.2 Scrapyd-Client 的使用
17.3 Gerapy 爬虫管理框架的使用
17.4 将Scrapy 项目打包成 Docker 镜像
17.5 Docker Compose 的使用
17.6 Kubernetes的使用
17.7 用 Kubernetes 部署和管理 Scrapy 爬虫
17.8 Scrapy 分布式爬虫的数据统计方案
17.9 基于Prometheus和Grafana的分布式爬虫监控方案
当前位置:
首页>>
技术小册>>
Python3网络爬虫开发实战(下)
小册名称:Python3网络爬虫开发实战(下)
### 15.11 Scrapy 对接 Pyppeteer:无头浏览器驱动的深度爬虫实践 在Python网络爬虫的开发领域中,Scrapy以其高效、可扩展的架构成为了众多开发者的首选框架。然而,面对日益复杂的网页结构和JavaScript动态渲染的内容,单纯依赖Scrapy的HTTP请求与响应处理往往显得力不从心。这时,结合无头浏览器(如Chrome的无头模式)进行页面渲染后再抓取,成为了一种有效的解决方案。Pyppeteer,作为Puppeteer的Python端口,允许我们控制Chrome或Chromium浏览器进行自动化操作,非常适合与Scrapy结合使用,以实现更高级的数据抓取功能。 #### 15.11.1 引言 随着Web技术的发展,越来越多的网站采用前端JavaScript来动态生成页面内容,这使得传统的基于HTTP请求的爬虫难以直接获取到页面上的所有数据。Scrapy虽然功能强大,但在处理这类由JavaScript动态加载的内容时,往往需要额外的工具来辅助。Pyppeteer正是这样一款工具,它能够模拟浏览器的行为,执行JavaScript代码,等待页面完全加载后再进行抓取,从而解决了Scrapy直接请求无法获取动态内容的难题。 #### 15.11.2 Pyppeteer基础 ##### 15.11.2.1 安装Pyppeteer 首先,确保你的Python环境已经安装。然后,通过pip安装Pyppeteer: ```bash pip install pyppeteer ``` 注意,由于Pyppeteer需要下载Chrome浏览器(或其Chromium版本)的特定版本,安装过程中可能会自动下载这些资源,因此请确保你的网络连接是通畅的。 ##### 15.11.2.2 Pyppeteer的基本使用 Pyppeteer的基本使用包括启动浏览器、创建页面、导航到URL、执行JavaScript脚本以及关闭浏览器等步骤。以下是一个简单的示例: ```python import asyncio from pyppeteer import launch async def main(): browser = await launch() page = await browser.newPage() await page.goto('https://www.example.com') content = await page.content() print(content) await browser.close() asyncio.get_event_loop().run_until_complete(main()) ``` 这个示例展示了如何异步启动浏览器,打开一个新页面,导航到一个URL,并打印出页面内容,最后关闭浏览器。 #### 15.11.3 Scrapy与Pyppeteer的结合 将Scrapy与Pyppeteer结合,主要思路是在Scrapy的Spider中嵌入Pyppeteer的浏览器控制逻辑,利用Pyppeteer渲染页面,然后将渲染后的页面内容(如HTML)传递给Scrapy进行解析。 ##### 15.11.3.1 设计思路 1. **启动Pyppeteer浏览器**:在Scrapy的Spider初始化时,或者在一个单独的服务中启动Pyppeteer浏览器。 2. **发送请求并渲染页面**:使用Scrapy的Request机制发送请求,但在回调函数中不直接处理响应,而是将URL传递给Pyppeteer进行页面渲染。 3. **获取渲染后的页面内容**:Pyppeteer渲染完成后,将页面内容(HTML)返回给Scrapy。 4. **解析页面内容**:Scrapy接收到渲染后的HTML后,使用Item Loader或Selectors进行解析,提取所需数据。 5. **关闭Pyppeteer浏览器**:在爬虫结束时,或在合适的时机关闭Pyppeteer浏览器。 ##### 15.11.3.2 示例实现 以下是一个简化的示例,展示了如何在Scrapy的Spider中嵌入Pyppeteer进行页面渲染: ```python import asyncio from scrapy import Spider from scrapy.http import Request from pyppeteer import launch class JsRenderedSpider(Spider): name = 'js_rendered' start_urls = ['https://www.example.com/dynamic-page'] async def fetch_with_pyppeteer(self, url): browser = await launch() page = await browser.newPage() await page.goto(url, {'waitUntil': 'networkidle2'}) content = await page.content() await browser.close() return content async def parse(self, response): # 注意:这里不能直接使用Scrapy的response,因为我们需要先通过Pyppeteer渲染 if isinstance(response.url, str): # 假设我们通过一个中间件将URL传递到这里 rendered_html = await self.fetch_with_pyppeteer(response.url) # 创建一个伪Response对象供Scrapy解析 from scrapy.http import TextResponse response = TextResponse(url=response.url, body=rendered_html, encoding='utf-8') # 使用Scrapy的解析逻辑 for item in self.parse_item(response): yield item def parse_item(self, response): # 这里使用Scrapy的Selectors或其他解析工具解析页面 # ... pass # 注意:由于Scrapy默认不支持异步,这里的示例需要在一个支持异步的环境中运行, # 如使用Scrapy的扩展或自定义中间件来兼容异步操作。 ``` **注意**:上述代码示例存在简化和假设的成分,因为Scrapy本身并不直接支持异步编程模型(基于Twisted的同步事件循环)。在实际应用中,你可能需要编写自定义中间件或使用Scrapy的扩展点(如downloader middlewares或spider middlewares)来桥接Scrapy和Pyppeteer之间的异步操作。此外,也可以考虑使用如Scrapy-Splash这样的现成解决方案,它内部集成了类似的浏览器渲染功能,但使用起来可能更为简便。 #### 15.11.4 性能与优化 虽然Pyppeteer为Scrapy提供了强大的动态内容抓取能力,但其性能开销也不容忽视。每个Pyppeteer实例都相当于运行了一个完整的浏览器,对系统资源的需求较高。因此,在设计和实现时,应注意以下几点以优化性能: 1. **复用浏览器实例**:尽可能复用Pyppeteer的浏览器实例,避免为每个请求都启动新的浏览器。 2. **限制并发**:合理控制并发请求的数量,避免同时启动过多的浏览器实例导致系统资源耗尽。 3. **优化页面加载**:利用Pyppeteer的页面加载选项(如`waitUntil`),减少不必要的网络请求和等待时间。 4. **异步与并发**:虽然Scrapy本身不支持异步,但可以考虑在Scrapy之外使用异步框架(如asyncio)来管理Pyppeteer的任务,以提高整体效率。 #### 15.11.5 结论 通过将Scrapy与Pyppeteer结合使用,我们可以有效地解决Scrapy在抓取JavaScript动态渲染内容时的局限性。尽管这带来了额外的性能开销和复杂性,但它为网络爬虫的开发提供了更广阔的可能性。在实际应用中,开发者应根据具体需求和环境条件,权衡利弊,选择最合适的工具和方案。
上一篇:
15.10 Scrapy 对接 Splash
下一篇:
15.12 Scrapy 规则化爬虫
该分类下的相关小册推荐:
Python编程轻松进阶(二)
Python合辑10-函数
Python高性能编程与实战
Python与办公-玩转Excel
Python甚础Django与爬虫
Python合辑5-格式化字符串
Python爬虫入门与实战开发(上)
Python3网络爬虫开发实战(上)
Python机器学习基础教程(上)
Python神经网络入门与实践
Python高并发编程与实战
Python合辑11-闭包函数