前面是利用axios+cheerio这对黄金搭档爬取数据,但是这种方式有一定的局限性,比如需登录验证的站点,或者做了某些反扒策略的网站等就无能为力了。
今天来介绍一种万能的办法——puppeteer。
安装
cnpm i puppeteer
这哥们比较牛x,它其实就是个chrome浏览器,安装这个插件足足有100多m呢。
它的原理是自动起个浏览器访问网站,然后可以将浏览器请求到的数据进行逐一分析提取,用这种方式爬数据,基本可以搞定所有网站。
好了,废话不多说,开始干活。
牛刀小试
let puppeteer = require('puppeteer');
async function test(){
//打开浏览器
let brower = await puppeteer.launch({headless:false});
//打开新页面
let page = await brower.newPage();
//打开电子书网站
await page.goto('https://sobooks.cc/');
//获取页面内容
page.$$eval('.nav li a',(ele)=>{
ele.forEach((item,i)=>{
console.log(item.innerHTML);//这个内容会在起的chrome浏览器的控制台输出
})
})
//监听浏览器控制台的console输出内容,在vscode可以看到打印信息
page.on('console',function(...arg){
console.log(arg);
})
}
test();
$$eval()是解析网页内容,2个$表示解析后得到的是多个对象信息;如果只是获取一个对象信息,就用$eval()。
这个例子我们获取电子书的分类信息,必然是多个了,而$$eval()返回的是promise,所以我们可以拿到所有电子书分类。
let puppeteer = require('puppeteer');
async function test() {
//打开浏览器
let brower = await puppeteer.launch({ headless: false });
//打开新页面
let page = await brower.newPage();
//输入网站信息
await page.goto('https://sobooks.cc/');
//获取页面内容
let res = await page.$$eval('.nav li a', (ele) => {
let arr = []
ele.forEach((item, i) => {
console.log(item.innerHTML);//这个内容会在起的chrome浏览器的控制台输出
let obj = {
href: item.getAttribute('href'),
text: item.innerText
};
arr.push(obj)
})
return arr;
})
console.log('获取电子书分类:', res);
//监听浏览器控制台的console输出内容,在vscode可以看到打印信息
// page.on('console',function(...arg){
// console.log(arg);
// })
}
test();
运行结果:
获取电子书分类: [
{ href: 'https://sobooks.cc/xiaoshuowenxue', text: '小说文学' },
{ href: 'https://sobooks.cc/lishizhuanji', text: '历史传记' },
{ href: 'https://sobooks.cc/renwensheke', text: '人文社科' },
{ href: 'https://sobooks.cc/lizhichenggong', text: '励志成功' },
{ href: 'https://sobooks.cc/jingjiguanli', text: '经济管理' },
{ href: 'https://sobooks.cc/xuexijiaoyu', text: '学习教育' },
{ href: 'https://sobooks.cc/shenghuoshishang', text: '生活时尚' },
{ href: 'https://sobooks.cc/yingwenyuanban', text: '英文原版' }
]
网友评论