puppeteer
时间: 2024-06-12
概述
puppeteer是一个优秀的浏览器。
安装
PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@16.2.0/install.ts
经常在使用脚本自动安装时会出错,这个时候最好手动下载可执行文件。
可以根据提示Uncaught Error: Could not find browser revision 1022525.
获得具体版本编号。
通常下载链接类似:
https://storage.googleapis.com/chromium-browser-snapshots/Linux_x64/1022525/chrome-linux.zip
,这个里面的1022525
是版本号。
基础知识
我们通过一个简单的实例来做一些了解。
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
headless: false, //有浏览器界面启动
defaultViewport: null,
timeout: 30000, // 默认超时为30秒,设置为0则表示不设置超时
slowMo: 500, //放慢浏览器执行速度,方便测试观察
args: ["--no-sandbox"],
});
const page = await browser.newPage();
await page.goto("https://www.baidu.com");
await page.close();
await browser.close();
})();
puppeteer.launch
每次都会启动一个Chrome
实例。
除此之外,我们也可以使用puppeteer.connect
连接一个已经存在的Chrome
实例。
首先启动实例。找到chrome的安装目录,通常在C:\Program Files (x86)\Google\Chrome\Application
下面。然后从命令行启动:
$ chrome.exe --remote-debugging-port=9222 --user-data-dir=C:\tmp
这样会在9222
端口启动一个调试实例。user-data-dir
好像必须要配置,否则连接不成功?然后可以在http://127.0.0.1:9222/json/version
查看到实例信息。
// 新建一个标签页(空白页或者带参数默认加载URL)
http://localhost:9222/json/new
http://localhost:9222/json/new?http://www.baidu.com
// 关闭一个标签页,传入该页面的id。
http://localhost:9222/json/close/477810FF-323E-44C5-997C-89B7FAC7B158
// 激活标签页。
http://localhost:9222/json/activate/477810FF-323E-44C5-997C-89B7FAC7B158
// 获取所有开打标签的信息。
http://loacalhost:9222/json/list
更详细的协议信息可以查看官网
const puppeteer = require("puppeteer");
let request = require("request-promise-native");
(async () => {
//通过 9222 端口的 http 接口获取对应的 websocketUrl
let version = await request({
uri: "http://127.0.0.1:9222/json/version",
json: true,
});
console.log(version);
//直接连接已经存在的 Chrome
let browser = await puppeteer.connect({
browserWSEndpoint: version.webSocketDebuggerUrl,
});
const page = await browser.newPage();
await page.goto("https://www.baidu.com");
await page.close();
await browser.disconnect();
})();
Browser对象API
方法名称 | 返回值 | 说明 |
---|---|---|
browser.close() | Promise | 关闭浏览器 |
browser.disconnect() | void | 断开浏览器连接 |
browser.newPage() | Promise(Page) | 创建一个Page 实例 |
browser.pages() | Promise(Array(Page)) | 获取所有打开的Page 实例 |
browser.targets() | Array(Target) | 获取所有活动的targets |
browser.version() | Promise(String) | 获取浏览器的版本 |
browser.wsEndpoint() | String | 返回浏览器实例的socket 连接URL ,可以通过这个URL 重连接chrome实例 。 |
Page对象API
这里要明确一些基本概念。元素的各种属性。
<view>这是innerText</view>
要获取这是innerText
需要用innerText
。
获取文本
let text = await page.$eval("#app", (ele) => ele.innerText);
获取元素的属性
比如,要获取下面这个元素的class
属性:
<div class="box" style="background: #F00">盒子</div>
let checkd = await page.$eval(`#app`, (el) => el.getAttribute("class"));
设置文本框值
为了保险一点,通常在输入前清空一下文本框比较好。
await page.$eval("#input", (ele) => ele.value = ""); // 清空文本框
await page.type("#mytextarea", "Hello"); // 立即输入
await page.type("#mytextarea", "World", { delay: 100 }); // 输入变慢,像一个用户
获取frame
ddlogin-iframe
是frame
的名字,也就是id
。
const ddloginIframe = page.frames().find((frame) =>
frame.name() === "ddlogin-iframe"
);
const qrcode = await ddloginIframe.$eval("#qrcode > img", (ele) => ele.src);
获取页面标题
page.title()
returns: <Promise<string>> 返回页面标题.
添加cookie
await page.goto(url);
const cookies = [{
"name": "cookie1",
"value": "val1",
}, {
"name": "cookie2",
"value": "val2",
}, {
"name": "cookie3",
"value": "val3",
}];
await page.setCookie(...cookies);