puppeteer?
高级API的node库,能够通过devtool控制headless模式的chrome或者chromium,它可以在headless模式下模拟任何的人为操作。
与cheerio的区别
cherrico本质上只是一个使用类似jquery的语法操作HTML文档的库,使用cherrico爬取数据,只是请求到静态的HTML文档,如果网页内部的数据是通过ajax动态获取的,那么便爬去不到的相应的数据。而Puppeteer能够模拟一个浏览器的运行环境,能够请求网站信息,并运行网站内部的逻辑。然后再通过WS协议动态的获取页面内部的数据,并能够进行任何模拟的操作(点击、滑动、hover等),并且支持跳转页面,多页面管理。甚至能注入node上的脚本到浏览器内部环境运行,总之,你能对一个网页做的操作它都能做,你不能做的它也能做。
例子:
爬取网页的数据,并把数据保存到数据库
//爬取疫情数据
const chalk = require("chalk")
const fs = require("fs")
const puppeteer = require('puppeteer');
const mysql = require("mysql");
//数据库信息根据自己的情况来配
const sqlInfo = {
host: '***.***.***.***',
user: 'root',
password: 'root',
database: '****',
port: 3306
};
// 创建mysql数据库连接
const con = mysql.createConnection(sqlInfo);
// 连接数据库
con.connect();
puppeteer.launch({
headless: false, //不使用无头模式使用本地可视化
//executablePath: "./Chromium/chrome-win/chrome.exe", //因为是yarn add puppeteer --ignore-scripts没有安装chromium,需要制定本地chromium的chrome.exe路径所在,刚才下载后解压后的全路径
//设置超时时间
timeout: 15000,
//如果是访问https页面 此属性会忽略https错误
ignoreHTTPSErrors: true,
// 打开开发者工具, 当此值为true时, headless总为false
devtools: true,
}).then(async browser => {
const page = await browser.newPage()
await page.goto('https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner', { waitUntil: "networkidle2" })
const moreBtn = await page.$(".Common_1-1-287_3lDRV2");
await moreBtn.click();
await page.waitForSelector('.VirusTable_1-1-287_3m6Ybq');
const data = await page.$$eval('.VirusTable_1-1-287_3m6Ybq', data => {
return data.map(a => {
return {
'area_name': a.children[0].children[0].children[1].innerText,
'newAdd': a.children[1].innerText,
'nowHas': a.children[2].innerText,
'total': a.children[3].innerText,
'cure': a.children[4].innerText,
'death': a.children[5].innerText,
}
});
});
let json = JSON.stringify(data,null,2)
console.log(chalk.green("所有数据抓取完毕:\n", json))
fs.writeFile('YQ.json', json, 'utf8', function(error){
if(error){
console.log(chalk.green(error));
return false;
}
console.log(chalk.blue('数据写入文件成功!'));
})
await browser.close()
// 开始插入数据库了
for(let i = 0;i<data.length;i++){
con.query("insert into yiqing(area, newAdd, nowHas, total, cure, death) values(?,?,?,?,?,?)",
[
data[i].area_name,
data[i].newAdd,
data[i].nowHas,
data[i].total,
data[i].cure,
data[i].death
],function(err) {
//这里呢,插入很可能出错,所以还是要走个形式判断一下嘛(虽然可能性基本为0只要数据库能连接上)
if (err) {
//输出错误
console.log(err);
} else {
//到这里,一条数据就插入成功了
console.log(chalk.blue('第'+(i+1)+'条数据成功插入数据库'));
}
});
}
}).catch(err => console.log(err))
爬到的数据:

写入到数据库中的数据:

