因为微信官方的限制,所以现在抓取公众号的历史文章不是一件简单的事情了,前两天通过多次尝试还是放弃直接抓取早读课
的历史文章。不过,找到了一条曲径
,记录如下。
分为两个阶段:
这段时间的文章,其实情封
已经总结好了,在公众号内回复目录就能获取一个pdf格式的文档,但是只有日期和题目信息,文章链接没办法直接复制获取,没办法直接使用。
毕竟对前端比较熟悉,所以想着能不能将pdf转成html格式,这样一来就可以为所欲为了,从中提取信息可是我们的强项。后来试了好几个工具,都没办法保留链接信息,而且导出的文字也是乱七八糟的。最后终于通过这个网站https://www.sodapdf.com/pdf-to-html/导出了一份含链接的html格式文档。
但是标题和日期也都很乱,很难获取到格式化好的信息,想着微信对具体文章的链接访问并没有限制,索性不如只收集其中的链接,有了链接,我们就可以通过爬虫的方式获取其他信息。
我的办法是先将其转换成html
格式,一共57页,然后逐一用浏览器打开,在Console面板
用如下代码获取所有链接:
var collection = document.getElementsByTagName('a');
var linkArr = [];
var _link;
for(var i =0, len = collection.length; i < len; i++){
_link = collection[i].href;
console.log(_link);
if(linkArr.indexOf(_link) === -1) linkArr.push(_link);
}
linkArr.join('\n');
本来想着拼在一起或者通过Node的fs
和cheerio
模块自动化处理,不过后来想了想量也不大就手动复制过来了。
情封
没有提供这之后的文章目录,也不好意思去麻烦他,不过我们可以通过抓取其他平台的信息来间接获取数据。
通过调研,发现搜狗微信搜索
貌似有这个功能,但是有如下两个弊端:
所以不得不放弃,后来又发现了即刻
网页版,有人早在11.10之前就已经创建了这个主题,而且上面的信息很全,所以我们可以通过抓取其网页信息来获得这段时间的数据。我们先通过Ctrl+End快捷键把这期间数据全部加载出来,然后同样在Console
面板中执行提取,代码同样很简单(哈哈,不就是一样的吗):
var collection = document.getElementsByClassName('message-link');
var linkArr = [];
var _link;
for(var i =0, len = collection.length; i < len; i++){
_link = collection[i].href;
console.log(_link);
if(linkArr.indexOf(_link) === -1) linkArr.push(_link);
}
linkArr.join('\n');
这样,通过上面两步,我们就获取到了迄今早读课所有文章的链接,下一步我们就可以通过爬虫抓取相应的信息。核心代码同样很简单(Node):
function _request(index) {
console.time(index);
request(ZAODUKE[index], function (error, response, body) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(body);
var title = _black($('h2').text() || '自定义标题');
var author = _black($('span.rich_media_meta_text').text() || '佚名');
var reg = /([0-9]{4}-[0-9]{2}-[0-9]{2})/g;
var tmp;
while ((tmp = reg.exec(body)) !== null) {
var date = tmp[0] || '';
}
var str = '- ' + date + '@' + author + ' [' + title + '](' + ZAODUKE[index] + ')' + '\n';
console.log(str);
fs.appendFile('data_1.txt', str, (error) => {
if (error) {
fs.appendFile('data_1.txt', index + ' error');
return false;
}
console.timeEnd(index);
if (!flag) return false;
if (index) {
index--;
} else {
return false;
}
setTimeout(() => {
_request(index);
}, parseInt(Math.random() * 10));
})
} else {
fs.appendFile('data_1.txt', index + ' error');
return false;
}
});
}
不过,这里面有个坑就是,其实时间并不是直接显示在页面上的,而是通过js代码动态填充的,所以通过cheerio
无法直接拿到对应的值,因此就利用正则的方式去取。
其实整个过程用到的技术非常简单,而且可以用更优雅的方式去做,无奈自己技术有限吧,献丑了,不过最终还是整理出来了,大家可以通过点击**{阅读原文}**直达,别忘了给颗小心心❤哦。
GraphQL
的文章的,不过点开啥也看不懂,还是默默的写下了这一篇,明天继续加油。(本篇完)