使用puppeteer爬取百度新闻
2021-06-28
Puppeteer 是一个由谷歌官方开发的 Node 库,用于通过 DevTools 协议控制 headless Chrome 或 Chromium,支持页面截图、PDF 生成、表单自动提交、UI 测试、性能分析等功能,适用于自动化测试和爬虫开发。
简介
puppeteer 是谷歌官方出品的一个通过 DevTools 协议控制 headless Chrome 的 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome,执行常见的操作,就像在真实的浏览器中一样,可以用来实现浏览器自动化测试或爬虫
puppeteer能做什么
页面截图,生成页面 PDF
抓取 SPA(单页应用)并生成预渲染内容(即“SSR”服务器端渲染)
自动提交表单,进行 UI 测试,键盘输入等
创建一个时时更新的自动化测试环境, 使用最新的 JavaScript 和浏览器功能直接在最新版本的 Chrome 中执行测试
捕获网站的 timeline trace,用来帮助分析性能问题
测试浏览器扩展
一些概念
headless模式:不显示浏览器界面控制浏览器
为什么要使用headless模式? 在一些本身就没有安装桌面应用程序的操作系统可以使用headless模式进行浏览器的控制,而不需要界面的支持
实例
1.初始化项
mkdir baidu-news-spider
cd baidu-news-spider
npm init -y
2.安装相关的依赖
npm install puppeteer
3.创建index.js,编写爬虫代码
//引入puppeteer
const puppeteer = require('puppeteer');
//引入node文件系统模块(fs)
const fs = require('fs');
//引入node文件路径模块(path)
const path = require('path');
//创建爬取数据的函数
let getNewList = async () => {
//创建一个Browser(浏览器)实例
const browser = await puppeteer.launch();
//在浏览器中创建一个新的页面
const page = await browser.newPage();
//打开百度新闻页面
await page.goto('http://news.baidu.com/');
//等待“国内”导航按钮出现
await page.waitForSelector('#channel-all > div > ul > li:nth-child(3) > a');
//点击“国内”导航按钮,进入国内新闻页面
await page.click('#channel-all > div > ul > li:nth-child(3) > a');
//等待“即时新闻列表”出现
await page.waitForSelector('#instant-news > ul');
//通过evaluate函数执行自定义的js代码获取要爬取的数据
const newList = await page.evaluate(() => {
//创建一个空数组接收爬取的数据
let data = [];
//获取所有即时新闻列表li元素
let elements = document.querySelectorAll('#instant-news > ul > li');
//利用循环将即时新闻列表的标题和链接地址添加到一个数组中
for (let i = 0; i < elements.length; i++) {
//获取新闻的标签
let title = elements[i].innerText;
//获取新闻的链接地址
let url = elements[i].firstChild.getAttribute('href');
//将获取到的标题和链接地址添加到数组中
data.push({
title,
url,
});
}
//返回数组
return data;
});
//关闭浏览器实例
await browser.close();
//返回爬取的数据
return newList;
};
//执行函数获取爬取的数据
getNewList().then((res) => {
//将爬取的数据转为json格式
let list = JSON.stringify(res);
//指定存储数据的json文件
let file = path.join(__dirname, 'newList.json');
//将爬取的数据写入json文件
fs.writeFile(file, list, (err) => {
if (err) {
console.log(err);
} else {
console.log('success');
}
});
});
4.运行
node index.js