Puppeteer入门教程
简介
这篇文章介绍Puppeteer相关知识,并编写了两个简单的使用Puppeteer的例子。包括从入门的介绍到功能的实现,教的很细,包会。
写在前面
所有的爬虫都要注意遵守相应的法律法规,访问速度不可以过快,过大的流量可能导致服务器故障。对于Puppeteer而言最佳的方案应该是完全拟人的速度或比真实用户稍快一些,可以添加一些等待函数。
如果需要更快的速度可以考虑使用不同的ip和客户机。
Puppeteer官方文档
官方文档链接: Puppeteer
中文官方文档链接: Puppeteer官方中文文档
Puppeteer简介
Puppeteer是一个由Google开发的Node.js库,用于控制Headless Chrome或Chromium浏览器,它广泛用于网页爬取、自动化测试和生成页面截图等任务。
这个工具对于很多人来说也许很陌生,但selenium相信更多人应该听说过,Puppeteer和selenium其实特别相似,都是控制浏览器进行一些指定的操作,如点击,移动鼠标,按下键盘等。
与selenium最大的不同在于,Puppeteer是基于浏览器开发者工具进行的操作,而selenium是基于webdriver。这也决定了Puppeteer更不容易被反爬工具所识别,因为它的操作在服务器端与用户的操作无异,而selenium的每一步操作都会被展示为webdriver。
当然Puppeteer能做的也不只是爬虫,由于它能在浏览器模拟用户的操作,因此也可用于一些web界面或后端接口的调试,本篇文章着重介绍爬虫知识。
什么情况下应该使用Puppeteer?
我认为爬虫大致可以分为几类
1.自己或所在公司的网站
这一类通常是自己的或公司或内部的一些网站或信息,因为种种原因不能直接获取,需要编写爬虫,且目标服务器能承受爬取的流量。那么使用 Python 的request库或 curl 命令即可,这样的速度相较于Puppeteer快的多得多,如果是这种情况不建议使用Puppeteer。
2.公开的网站,没有严格的反爬机制,同步加载的页面
这一类应该是最常见的需求,毕竟大多数公开的网站不会设置太严格的反爬机制,有很多直接request就可以,少部分简单的反爬只要有user-agent也能正常获取信息,这种情况下更建议使用 Python 的request库或者 js 的axios库,这些库能获取指定链接的内容,后续可以通过其他工具解析。因为这些库并不需要渲染页面,对资源占用更小,速度也更快。此外,这类库的逻辑也相对更简单,代码更容易编写。
3.公开的网站,有反爬机制或异步渲染的页面
这是非常建议使用Puppeteer的场景,比如html和数据是分两个请求发送的,如果只使用request请求数据,可能会被判断为机器人导致被封禁。又比如或者页面是异步加载,使用request可能只能获得其中一个,只拿到了html没拿到数据那可就白爬了。但Puppeteer能帮助我们获取到Dom树(也就是最终加载完的html),我们可以解析Dom树,这样就能避免数据不全的问题。
对于反爬机制而言,Puppeteer也提供了更丰富的绕过机制的可能性,因为它完整地渲染了页面,也提供了各种鼠标和键盘事件,一些普通的机器人验证还是很容易绕过的。复杂的机制也可以通过较难的函数破解。
4.非公开的网站
不可以爬!不可以爬!!例如学校存储成绩的后台,公司的业务管理后台等,可以通过一些手段伪造验证进入,但是爬的话你和牢饭仅几步之隔。爬虫学得好,牢饭吃到饱就是这么来的。因为它非公开,访问记录还是很容易通过日志查出来的。
配置环境
安装nodejs
nodejs的安装包在nodejs官网就能找到,推荐安装左侧的Recommend For Most Users版本,因为最新版本可能会有一些BUG,而且我们目前的需求并不需要特别高的版本。
安装nodejs并不难,一直Next即可
安装完成
在cmd中输入node -v
如果能显示版本号即安装成功
配置项目环境
我们打开一个项目文件夹,输入npm init -y
新建一个项目
等待执行完毕后 输入npm install puppeteer
在当前项目中安装puppeteer库
正确安装后输出如下:
D:\VSCode Projects\sample_puppeteer>npm install puppeteer
added 111 packages, and audited 112 packages in 32s
9 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
D:\VSCode Projects\sample_puppeteer>
到这里我们的环境就配置完成了,第一次执行npm install puppeteer
时它会自动下载并安装最新版本的Chromium,简单来说这是一个和Chrome很类似的专用于测试的浏览器,默认情况下puppeteer也正是操作这个浏览器进行一系列的操作,在Windows上文件大小大约是280MB。
代码-基础功能实现
让我们首先做一个基础的效果 爬虫界的hello world(?)
在我们刚刚的项目目录里新建一个js文件,我这里叫 crawler_sample.js
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
随后可以粘贴上面的代码,这段代码的功能是跳转到example.com并在项目根目录下生成一个example.png,也就是我们刚刚截到的图。
在项目根目录下打开cmd,输入node crawler_sample.js
执行刚刚的js代码
我们可以发现根目录生成了一个叫做 example.png 的文件,这个图片也就是example.com的截图。
那么在刚刚的几秒发生了什么呢?
首先 const browser = await puppeteer.launch();
打开了一个无头浏览器实例(可以理解为在后台运行的浏览器)
然后 const page = await browser.newPage();
在这个浏览器创建了一个page对象,也就是打开了一个新标签页
然后 await page.goto('https://example.com');
让这个新标签页访问https://example.com
然后 await page.screenshot({path: 'example.png'});
对页面进行了一次截屏,并将截取到的页面图片保存在同级目录,命名为 example.png
最后 await browser.close();
关闭一开始创建的无头浏览器实例
没错 它的操作是不是特别像人类的操作?想象一下如果你需要去某个网站截屏,是不是也是类似的操作流程。因此,Puppeteer的一大特性就是能完全模拟用户的操作,在其他的爬虫或测试中也是一样的逻辑。
代码-基础功能进阶
好的,现在你已经实现了用工具前往某网站并截图,现在让我们尝试稍微添加一些常见的优化
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false}); // headless设置为false,让浏览器不是后台运行,而是直接展示在前端
const page = await browser.newPage();
await page.setViewport({ // 将页面大小设置为1280像素宽,900像素高,放大1倍(默认也是1)
width: 1280,
height: 900,
deviceScaleFactor: 1,
});
await page.goto('https://example.com');
await page.waitForTimeout(3000); // 暂停3秒
await page.screenshot({path: 'example.png'});
await browser.close();
})();
这几个是相对常用的功能,headless设置为false我们就可以直接看到页面操作的过程,这在调试代码中很常用,也方便我们看到是哪里出了错误
设置像素是因为默认的800* 600px真的太小了,如果直接看的话真的有些难受,你可以调整为你屏幕适合的大小,我这边设置为了1280* 900px
同样很常用的await page.waitForTimeout(3000);
让程序暂停3秒,类似于python中的time.sleep(3),但js语言中单位是毫秒,因此3秒就是3000
开发中你也可以注释掉await browser.close();
,这样浏览器实例就一直不会被关掉,你可以更直观地看到程序的状态,但是真正上生产环境的时候要记得加上哈,不然代码会一直无法自然结束