Node爬取微博、知乎热点
微博和知乎作为国内两大吃瓜平台,每天的热点不断,辐射不同领域,对我们粗略了解当前社会可谓是方便快捷,然而手机app中广告太多,稍不注意就帮我买东西,实在是烦人,于是我采用技术手段来获取我所需要的(只吃瓜,不评论)。
必要工具
- cheerio
- superagent
Superagent
它是一个灵活的Node.js HTTP请求库,支持Promise API,使得从URL获取内容变得轻而易举。由于微博和知乎的热点页面不是单页面应用(SPA),使用Superagent可以轻松地获取HTML文本,成为我们探索的第一步。
Cheerio
获取HTML文本后,Cheerio便是我们解析这堆文本的利器。它提供了类似于jQuery的语法,使得操作DOM成为一种享受,帮我们轻松筛选和获取所需数据。
目标网站
我们需要从微博、知乎站点获取cookie,这样爬虫才能获取到数据,微博不需要登录就可以拿到,知乎需要登录。
分析网站结构
首先我们看看微博的结构,如下图
可以看到以class td-02就是我们需要的节点,其包括了热点话题名称、讨论数量,td-01、td-03对我来说不太需要就不处理。
接下来我们看知乎的分析,知乎比微博稍微复杂点,内容也多一些。
可以看到class HotItem就是每一个热点的容器,其下面后标题、简介、热度、配图。
准备工作
- pnpm init
- pnpm install cheerio superagent lodash
具体代码
weibo.js
const cheerio = require('cheerio');
const superagent = require('superagent');
const _ = require('lodash');
class Weibo {
async initProcess() {
const url = 'https://s.weibo.com/top/summary';
const cookie = '请自行复制后粘贴';
const html = await this.getRawHtml(url, cookie);
const hotInfo = this.getHotInfo(html);
console.log(hotInfo);
}
async getRawHtml(url, cookie) {
const request = superagent.get(url);
request.set('cookie', cookie);
const data = await request;
return data.text;
}
getHotInfo(html) {
const $ = cheerio.load(html);
const hotKeyElements = $('.td-02');
const hotKeys = [];
// 去重
const tmpTitles = [];
hotKeyElements.map((index, element) => {
const a = $(element).find('a');
const title = a.text();
const span = $(element).find('span');
// 默认top为999999999
let count = 999999999;
if (index) {
count = parseInt(span.text(), 10);
}
if (tmpTitles.includes(title)) {
return '';
}
tmpTitles.push(title);
hotKeys.push({ title, count });
return '';
});
return _.uniqBy(hotKeys.filter(item => item.title && !_.isNaN(item.count)), 'title');
}
}
const weibo = new Weibo();
weibo.initProcess();
zhihu.js
const cheerio = require('cheerio');
const superagent = require('superagent');
const _ = require('lodash');
class Zhihu {
async initProcess() {
const url = 'https://www.zhihu.com/hot';
const cookie = '请自行复制后粘贴';
const html = await this.getRawHtml(url, cookie);
const hotInfo = this.getHotInfo(html);
console.log(hotInfo);
}
async getRawHtml(url, cookie) {
const request = superagent.get(url);
request.set('cookie', cookie);
const data = await request;
return data.text;
}
getHotInfo(html) {
const $ = cheerio.load(html);
const hotItemElements = $('.HotItem');
const hotKeys = [];
hotItemElements.map((index, element) => {
const title = $(element).find('.HotItem-title').text();
const img = $(element).find('.HotItem-img img').attr('src');
const hot = $(element).find('.HotItem-metrics--bottom').text() || $(element).find('.HotItem-metrics').text();
const url = $(element).find('.HotItem-content > a').attr('href') || '';
const question_id = parseInt(url.split('/').pop() || '', 10);
if (question_id) {
hotKeys.push({
title,
img: img || '',
url: url || '',
hot: parseInt(hot, 10),
question_id: String(question_id),
});
}
return '';
});
return _.uniqBy(hotKeys.filter(item => item.question_id && !_.isNaN(item.hot)), 'question_id');
}
}
const zhihu = new Zhihu();
zhihu.initProcess();
运行结果如下
自行扩展
实施上述方案后,我们得以迅速掌握微博与知乎的热点动态,筛选出有价值的信息。而这一切,只是冰山一角。在获取了这些珍贵数据之后,接下来可以考虑运用node-schedule
等工具定时爬取最新内容,并将其存储、分析,抑或是以网站形式呈现,甚至进行高级的热词分析等,皆看各位的创意发挥了。
Tags
爬虫
Node
微博
知乎