Puppeteer数据提取
上一章已经和大家一起了解了Puppeteer,本章会和大家一起学习一下puppeteer简单的数据提取功能,以获取掘金沸点热门为例。
准备工作
node环境,vscode(或其他)
安装 Puppeteer
首先,需要使用 npm 或 yarn 安装 Puppeteer:
npm install puppeteer
或者
yarn add puppeteer
模拟登录
模拟登录分为:
- 通过dom交互进行模拟真实登录
- 通过写入cookie模拟已登录环境
模拟真实登录
通过Puppeteer提供的api来实现,主要有
page.waitForSelector(selector) //要等待的元素选择器
page.click(selector) //点击元素
page.type(selector,text) //要输入内容的元素选择器如果有多个匹配的元素,输入到第一个匹配的元素,要输入的内容
代码如下:
const puppeteer = require("puppeteer");
const cookieObjects = require('./cookie');
(async () => {
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()
const navigationPromise = page.waitForNavigation()
await page.goto('https://juejin.cn/')
await page.setViewport({ width: 1745, height: 852 })
await page.waitForSelector('.nav-list > .right-side-nav > .nav-item > .login-button-wrap > .login-button')
await page.click('.nav-list > .right-side-nav > .nav-item > .login-button-wrap > .login-button')
await page.waitForSelector('.login-main > .panel > .input-group > .dropdown-box > .input')
await page.click('.login-main > .panel > .input-group > .dropdown-box > .input')
await page.waitForSelector('.auth-body > .login-body > .login-main > .other-login-box > .clickable')
await page.click('.auth-body > .login-body > .login-main > .other-login-box > .clickable')
await page.waitForSelector('.login-main > .panel > .input-group > .focus > .input')
await page.click('.login-main > .panel > .input-group > .focus > .input')
await page.type('.login-main > .panel > .input-group > .focus > .input', '1234567
await page.waitForSelector('.login-main > .panel > .input-group > .input-box > .login-password')
await page.click('.login-main > .panel > .input-group > .input-box > .login-password')
await page.type('.login-main > .panel > .input-group > .input-box > .login-password', '1234567
await page.waitForSelector('.auth-body > .login-body > .login-main > .panel > .btn')
await page.click('.auth-body > .login-body > .login-main > .panel > .btn')
await page.waitForSelector('#secsdk-captcha-drag-wrapper > .secsdk-captcha-drag-icon > .sc-kkGfuU > svg > path')
await page.click('#secsdk-captcha-drag-wrapper > .secsdk-captcha-drag-icon > .sc-kkGfuU > svg > path')
await navigationPromise
})()
运行:
Hadless Recorder
大家看到这里估计会吐槽写的好乱,其实这里是想和大家介绍一款工具Headless Recorder,在chrome插件记录你在网页上的操作并且自动生成puppeteer脚本,也可以通过github下载后执行npm i
,npm run build
然后在chrome浏览器安装即可。
安装好后可以通过点击红色按钮来进行录制,中间可以暂停,点击结束后该工具会生成脚本,点击Copy即可复制,
将生成好的脚本进行简单修改后即可运行。在设置选项里有ywright/puppeteer launch options可以取消勾选,这样每次生成的脚本会默认打开浏览器。
写入cookie模拟已登录环境
写入cookie模拟已登录环境是本人比较推荐的一种方式,用起来非常简单稳定,因为在使用交互方式时,很多场景下都会有验证码(后面会讲到)所以现在推荐大家使用cookie,
Puppeteer设置cookie主要使用到了page.setCookie(cookie)
,注意这里的cookie格式要标准,这里推荐一款插件 EditThisCookie这里是他的github。
将导出的标准cookie存放到单独文件中如:cookie.js
,主代码如下:
const puppeteer = require("puppeteer");
const cookieObjects = require('./cookie');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 }); // 设置浏览器视窗大小
cookieObjects.forEach((cookie) => {
page.setCookie(cookie);
});
await page.goto("https://juejin.cn/pins");
})()
运行代码,打开后即是登录后的沸点
提取数据
现在已经打开沸点页面,可以使用Puppeteer提供的page.evaluate
实现,代码如下:
const puppeteer = require("puppeteer");
const cookieObjects = require('./cookie');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 }); // 设置浏览器视窗大小
cookieObjects.forEach((cookie) => {
page.setCookie(cookie);
});
await page.goto("https://juejin.cn/pins");
await page.waitForSelector("#juejin > div.view-container.pin_container > main > main > div.stream.no-topic-list.no-hot-new-tag > div.stream-wrapper > div.pin-list-view > div > ul > span > li");
let pins = []
pins = await page.evaluate((pins) => {
const list = document.querySelectorAll('#juejin > div.view-container.pin_container > main > main > div.stream.no-topic-list.no-hot-new-tag > div.stream-wrapper > div.pin-list-view > div > ul > span > li')
list.forEach(item => {
console.log(item)
pins.push({
auth: item.querySelector('.username').innerText,
content: item.querySelector('.content').innerText
})
})
return pins
}, pins)
console.log('------------')
console.log(pins)
})()
这样我们就能提取到沸点的数据。
github:github.com/puppeteer/p…