最近在研究前端爬虫,刚好看到Puppeteer,就想着分享给大家,于是有了这篇。
爬虫主要的目标是自动地做些什么事情,包含资料搜集、测试、执行任务…等等,借此提高工作效率。
网路爬虫的主要优势和需求主要体现在以下几个方面:
自动化测试(automated testing)
模拟使用者操作、提交表单等
可以为应用程式开发、软体测试和网站管理等提供重要的支援
减少人力成本,建立工作模式(SOP)。
资料收集(data collecting)
缩短了手动收集和处理资讯的时间,提升了工作效率
可以对资讯进行解析,并且有结构性的储存,便于后续的使用或分析
自动化执行任务(automated tasks)
包含以上内容。
在使用过程中也需要注意尊重网站拥有者的权益,遵守机器人排除协定(Robots Exclusion Protocol)和各种相关法规,避免对被爬取的网站造成不必要的负担或侵犯。
常见的网页爬虫套件这三个套件(Puppeteer、Cheerio 和Selenium)在前端爬虫中扮演不同的角色,各自有其优缺点和特点。
优点:
提供了完整的浏览器控制能力,可模拟使用者的操作浏览器行为,支援JavaScript、html、css 的渲染和交互。
可以用来进行网页自动化能力,包括页面导航、表单填写、截图、PDF 生成等工作。
具有丰富的API 可以直接操作网页上的元素和事件。
Puppeteer 是一个由Google 开发的Node.js 库,专门用于Chrome 浏览器的控制和操作。
Puppeteer 使用真实的浏览器进行操作,因此能够处理JavaScript 渲染的页面,适用于单页应用程序(SPA)和动态网站的爬取。
可以模拟用户交互,使其在网站上执行各种操作,如点击、滚动等。
缺点:
需要较多的系统资源,因为它启动了一个完整的浏览器进程用于模拟了完整的浏览器,。
相对于其他轻量级的爬虫工具,Puppeteer 比较慢且耗时。
如果只是需要解析静态网页内容,可能显得过于庞大。
需要更多的学习成本,因为它使用了一套复杂的API。
优点:
非常轻量级,适用于解析静态HTML 内容。
语法简单易懂,使用jquery 风格的API,方便选择、操作和提取dom 元素。
适合处理大量数据,效率较高。
Cheerio 是一个基于Node.js 的HTML 解析库,用于解析和操作HTML 文档。它非常适静态网页的爬取,尤其是当你只需要从页面中提取数据而不需要进行交互时。
轻量级且简单易用,适合快速开发小型爬虫。
缺点:
Cheerio 只能处理静态内容,无法执行JavaScript,因此无法处理需要JavaScript 动态生成的内容。
不支援浏览器渲染,无法模拟浏览器行为。
Cheerio 无法处理JavaScript 渲染的页面,因此对于SPA 和动态网站可能不太适用。
不能模拟用户交互,无法执行类似点击和提交表单的操作。
优点:
跨平台性强,支援多种浏览器(Chrome、Firefox 等)。
可以模拟人工操作,支援JavaScript 执行。
可以用多种语言进行控制,如Python、Java、JavaScript 等。
Selenium 是一个跨浏览器的自动化测试工具,可以模拟用户在浏览器中的操作。它支持多种编程语言,并且可以用于爬取需要用户交互的网站。
能够处理JavaScript 渲染的页面,适用于SPA 和动态网站。
缺点:
相较于Puppeteer,Selenium 在性能和速度上可能稍微较慢。
安装和配置有一定复杂度,需要下载驱动器以及设定环境变数等。
Selenium 需要下载和配置浏览器驱动程序,而且通常比其他两种库更慢,因为它模拟了真实的浏览器行为。
对于简单的静态网页爬取任务,Selenium 可能会显得过于复杂。
如果你需要模拟完整的浏览器行为且操作较多互动性的内容,Puppeteer 和Selenium 可能更适合你。
如果你只需要简单地解析静态HTML 页面,Cheerio 是一个轻量级的选择。
每个套件都有其独特的优势和限制,根据你的具体需求选择合适的工具。
Puppeteer 是由Google 开发的Node.js 函式库,提供方便的API 来进行网页测试、屏幕截图和网页爬虫等应用,但仅限于使用Chromium 浏览器引擎的浏览器,例如:Google Chrome 或Microsoft Edge。
Chromium 浏览器!== Chrome 浏览器
Chromium是一个由Google 主导的开源浏览器项目,它提供了一个开放的、可自由使用的浏览器引擎,供开发人员使用。
Chromium 虽然和Chrome 九成像,但它其实是Chrome, Edge 的基础版本。
Chromium 提供了Chrome 的基本架构和核心功能,而Chrome 在这个基础上增加功能,成为一个提供给使用者的完整产品。
Chromium 就像是汽车引擎,而Chrome 就像是整台汽车
Puppeteer 的许多用途包括:
产生页面的截图和PDF
爬取SPA(单一页面应用程式)并产生预渲染内容(即"SSR"(伺服器端渲染))
UI 自动化测试,模拟表单提交,键盘输入,点击等行为
建立一个最新的自动化测试环境。
使用最新的JavaScript 和最新的Chrome 浏览器执行测试案例
捕获网站的timeline trace(时间轴跟踪),用来帮助分析效能问题
测试Chrome 扩充功能
Puppeteer 预设是以headless(无头)模式运行。headless 模式是指在爬虫过程中不显示浏览器视窗画面,虽然看不到画面但仍然会执行画面的渲染过程,也就是说HTML 的解析、CSS 的套用和JavaScript 都会正常执行,这样才能确保画面内容是正确且完整的。
因为无头模式少了显示结果的处理不会做屏幕绘制,所以相较于有头模式,更能节省资源;但是在开发上有头模式会方便许多,因为浏览器会将渲染好的页面展示出来,包含了:
处理用户的交互
应用动画效果
重新绘制页面元素
任何有关图像输出至浏览器的过程…等
无论在无头模式或有头模式下,一定要做关闭浏览器的动作,无头模式虽然看不到浏览器画面,实际上背景仍然会有一个浏览器真的在跑。所以如果爬虫完没有确实地关闭浏览器,那么整个程式就仍然还在运行中,需要手动Ctrl + C 停止执行。在写脚本的时候,一定要记得在结束或是发生错误的地方把浏览器关闭,才能好好地释放资源。
如果希望变更为一般模式,可以藉由设定选项变更为有头模式,如下:
// 一般模式(有頭模式)
const browser = await puppeteer.launch({
headless: false,
});
// 無頭模式(Puputeer 預設模式)
const browser = await puppeteer.launch({
headless: 'new',
});
// 關閉瀏覽器
browser.Close()
Puppeteer 会下载最新版本的Chromium(~170MB Mac,~282MB Linux,~280MB Win),以保证可以使用API。
# 使用 npm
npm i puppeteer
# 使用 yarn
yarn add puppeteer
puppeteer-core
# 使用npm
npm i puppeteer-core
# 使用yarn
yarn add puppeteer-core
自1.7.0 版本以来,官方维护团队都会发布一个puppeteer-core 函式库,是一个的轻量级的Puppeteer 版本,用于启动现有浏览器安装或连接到远程安装。
起手式
const puppeteer = require("puppeteer");
(async () => {
// 啟動瀏覽器並開啟一個新的空白頁面
const browser = await puppeteer.launch();
const page = await browser.newPage();
// 將頁面導航至 URL
await page.goto("https://developer.chrome.com/");
// 關閉
await page.close();
await browser.close();
})();
常用语法
const puppeteer = require("puppeteer");
(async () => {
// 啟動瀏覽器並開啟一個新的空白頁面
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1400, height: 900 },
});
const page = await browser.newPage();
// 前往指定 URL
await page.goto("https://developer.chrome.com/");
// 設定瀏覽器尺寸
await page.setViewport({ width: 1080, height: 1024 });
// 在欄位,輸入文字 "js-text"
await page.type(".devsite-search-field", "js-text");
// 操控鍵盤 "Enter"
await page.keyboard.press("Enter");
// 等待元素,出現在頁面中
const searchResultSelector = "a.gs-title";
await page.waitForSelector(searchResultSelector);
// 點擊元素
await page.click(searchResultSelector);
const textSelector = await page.waitForSelector(".devsite-page-title");
// 在瀏覽器執行 JavaScript,取得元素資訊
const fullTitle = await textSelector?.evaluate((el) => el.textContent);
// 取得頁面尺寸資訊
const dimensions = await page.evaluate(() => {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
};
});
// 列印結果
console.log('The title of this blog post is "%s".', fullTitle);
console.log("Dimensions:", dimensions);
// 畫面截圖
await page.screenshot({ path: "example.png" });
await page.goBack(); // 回到上一頁
await page.goForward(); // 前往下一頁
await page.reload(); // 重新整理
await page.close();
await browser.close();
})();
5 天前