知乎应该很多人没事的时候都会去看, 毕竟知乎上平均年收入几十万, 日常出国. 哈哈 听朋友说, 今天闲来无事写了一个爬取知乎答案列表的爬虫. 当然知乎有营养的内容还是很多的
之前写过一次抓答案列表接口的爬虫, 感觉不太好, 还得找每个问题的请求接口, 这次使用puppeteer
来通过页面显示内容抓取
Puppeteer
是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。Puppeteer 默认以 headless 模式运行,但是可以通过修改配置文件运行“有头”模式。
我们随便打开一个知乎的问题, 可以看到下面就是答案列表, 点击查看所有回答, 然后下滑到底加载, 就是这么个逻辑;
我们的抓取方式就是这样, 访问到网址之后, 先点击页面内的查看所有回答按钮, 然后滑到底加载更多回答, 重复执行下滑到底的动作, 一直加载更多的回答, 加载到你想要的数量或者加载完回答之后, 开始处理得到的数据, 然后写到json文件或者excel文件里, 当然这次我写的只能抓取纯文字的内容, 有图片视频的的没有处理
下面是完整的代码, 注释我写的很清楚
代码一共需要安装两个依赖
- puppeteer
- node-xls
第一个安装可能会有点慢, 第二个是插入excel的node库
const puppeteer = require("puppeteer");
const fs = require("fs");
const NodeXls = require('node-xls');
var TOTAL = 10; // 你想抓取的答案数量, 如果想抓取所有, 等于0
(async () => {
console.log("开始抓取数据...");
const browser = await puppeteer.launch();
var page = await browser.newPage();
await page.goto("https://www.zhihu.com/question/287642868/answer/1028962960", {
timeout: 0, // 等待时间无限长
waitUntil: "networkidle2"
});
// 提取所需元素
const title = await page.$eval("h1", e => e.innerText)
const content = await page.$eval(".QuestionRichText", e => {
if (e.querySelector(".QuestionRichText-more")) {
e.querySelector(".QuestionRichText-more").click();
}
return e.innerText
})
const tag = await page.$$eval(".QuestionHeader-topics .Popover", e =></