今天发现了一个很好玩的node库,Puppeteer,准备玩一下。先来看看官方的介绍。
Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。换句话说,它最大的特点就是它的操作Dom可以完全在内存中进行模拟既在V8引擎中处理而不打开浏览器。
那么 Puppeteer可以用来做什么?
- 可以生成页面PDF文件;
- 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染));
- 自动提交表单,进行 UI 测试,键盘输入等;
- 创建一个时时更新的自动化测试环境。 使用最新的 JavaScript; 和浏览器功能直接在最新版本的Chrome中执行测试;
- 捕获网站的 timeline trace,用来帮助分析性能问题;
- 测试浏览器扩展;
这么多优秀的功能,简直是前端神器。
Puppeteer 因为需要使用 async / await,所以尽量保证Node的版本在v7.6.0以上。
本文主要拿它的爬虫功能玩一玩。
--------------------—--------------假装分隔符--------------------------------------------
安装很简单,一句话搞定: npm i puppeteer or yarn add puppeteer
安装好以后,写个例子玩一下:
const puppeteer = require('puppeteer');
(async() => {
// 配置浏览器
const browser = await puppeteer.launch({headless: true});
// 打开一个新页面
const page = await browser.newPage();
// 进入页面
await page.goto('');
// 截个图看一下
await page.screenshot({
path: 'image.png',
fullPage: true,
});
})();
复制代码
没错,我们准备爬一下掘金的数据。看一下刚才的截图
很神奇有木有,几行代码就实现了长截图。
进去了网址,接着玩一下它的输入框。
// 进入页面
await page.goto('');
// 找到输入框的class
await page.type('.search-input', "puppeteer");
// 按下enter键
await page.keyboard.press('Enter');
// 等两秒钟,模拟一下用户输入,也要登一下数据刷出来
await page.waitFor(2000);
// 再截个图看一下
await page.screenshot({
path: 'image.png',
fullPage: true,
});
复制代码
查到数据了!!也就是仅仅几行代码,就实现了搜索。可以脑补一下,模拟用户登录哦~~~
截图和操作输入框我们都玩过了,那我们就可以做一个简单的小东西,实现一个页面,在搜索框里面输入关键字,查找出掘金的相关文章。
正常操作,
安装一下express yarn add express
创建index.js
const express = require('express');
const app = express();
const ejs = require('ejs');
const main = require('./puppeteer');
app.set('view engine','ejs');
app.use('/index', (req, res) => res.render('index'));
app.use('/search', async(req, res) => {
const { value, more } = req.query;
const list = await main(value, more);
res.send(list);
});
app.listen(3000, () => console.log('Example app listening on port 3000!'));
复制代码
我们用到了ejs模板,有时间的童鞋可以写一个漂亮美观的前端页面~
在同级目录下创建views目录,然后再创建index.ejs
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>node爬虫</title>
</head>
<body>
<ul class="list"></ul>
<input type="text" class="input_value">
<span class="search" style="cursor: pointer; color: blue;">Search</span>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$('.search').click(() => {
$.ajax({
type: 'GET',
url: '/search',
data: {value: $('.input_value').val()},
success: res => $('ul').html(res.reduce((total, item) => total + `<li><a target="_blank" href="${item.href}">${item.title}</a></li>`, ''))
});
});
</script>
</html>
复制代码
接着创建关键爬虫代码:
const puppeteer = require('puppeteer');
async function main(value) {
// 配置浏览器
const browser = await puppeteer.launch({headless: true});
// 创建一个新页面
const page = await browser.newPage();
// 进入网址
await page.goto('');
// 找到搜索框
await page.type('.search-input', value);
// 点击搜索
await page.keyboard.press('Enter');
// 等待文章列表出来
await page.waitForSelector('.main-list');
// 截图看一下
await page.screenshot({
path: 'image.png',
fullPage: true,
});
// 找一下文章容器
const list = await page.$('.main-list');
// 组合一下文章标题和链接
const result = await list.$$eval('.entry-link', e => e.map(v => ({
href: v.href,
title: v.querySelector('.title').firstChild.innerText
})));
return result;
}
module.exports = main;
复制代码
就创建三个文件,node index.js一下,看看效果~ (界面略丑)
好像少了点,再爬多一点, 把滚动条往下滑到3000的位置,试一下:
// 等待文章列表出来
await page.waitForSelector('.main-list');
// 把滚动条滚动到指定位置
await page.evaluate(() => window.scrollTo(0, 3000));
// 等待时间根据滚动条的位置要增加,不然来不及反应
await page.waitFor(2000);
复制代码
没截全,然后脑补一下,是不是可以用自己写的爬虫去爬自己的爬虫,来搞个长截图~(我就不试了,留给你们~)
好了,Puppeteer的确很强大,也很好玩,大家有兴趣的话,可以用它来爬一些自己感兴趣的网站。~
最后附上全部代码地址: github