微信公众号 文章的爬虫系统
优采云 发布时间: 2020-08-13 19:03差不多俩个礼拜了吧,一直在调试关于微信公众号的文章爬虫系统,终于一切都好了,但是在这期间遇到了好多问题,今天就来回顾一下,总结一下,希望有用到的小伙伴可以学习学习。
1、做了俩次爬虫了,第一次怕的凤凰网,那个没有限制,随便爬,所以也就对自动化执行代码模块放松了提防,觉得很简单的,但是毕竟不是这样的,我被这个问题困惑了好几天,差不多4天的一个样子,因为搜狗做的限制,同一个ip获取的次数多了,首先是出现验证码,其次是就是访问限制了,直接就是不能访问,利用 request得到的就是访问次数过分频繁,这样子的提示,所以说开发过程中最头痛的不是代码的编撰,而是测试,写完代码不能立刻测试,这种觉得相信大多数的程序员是不能喜欢的,我如今写的程序是每晚执行三次,这样的一个频度挺好,而且由于是多公众号采集嘛,每个公众号之间的间隔时间也的有,要不然同时访问十几个公众号的上百篇文章也是不现实的,说到这儿插一句,怎么使每位公众号怕去玩过后,等一段具体的时间,在执行下一个,最后用的setInterval函数解决的,
每过80秒执行一个公众号,把每次的执行代码讲到hello中,泡的有点远了,收一收哈,说说cron这个包,自动化执行,npm官网上只给了一个反例,但是我这个指桑拿可能是有点压制的厉害,不能否玩却理解他的用法,然后我说理解不了怎样办啊,上网搜呗,百度,cron包的具体用法,一看,嚯,还很多,于是就看啊看啊,但是仔细以剖析就不是这么回事儿了,都是屁话,没哪些用,网上通常的用法中都带有一个问号,但是我加上问号的时侯,就报错了,所以说都是胡扯,最后在朋友组的一个后端技术讨论群中说了一声,还真有热心的群友,给我找了一个链接,我进去一看,试了一下,还行,所以呢,非常谢谢这个帮助我解惑的朋友,再次我把qq群号,和链接附上,方便正在看这篇文章的你学习,QQ群号:435012561,链接:,这个链接上面说的挺好,至少能用,这里我挺好到一个问题,就是timezone,我们之前用过一次,用的是纽约时间,但是此次显著不行啊,要用俺们中国的时间啊,但是我试了几次上海的不行,重庆的可以,所以我就用了上海的。
2、这里要说的是,从地址栏获取参数的问题,我上一个做的没问题,但是这个不知道如何就不行了,上一个从地址栏得到的是数字,但是这个得到的是字符串,再加上mongodb中的对数组的要求还是很严格的,所以一个分页功能也困惑了我几个小时吧,最后是如何解决的呢,是通过我加的一个mongodb的讨论群,在里面问了一句这是如何了,发了个截图,里面就有一个热心的网友说你这显著是传入的数据格式不对啊,一语惊醒梦中人,我说是啊,然后就把得到的参数,我用Number()函数处理了一下,让string类型的数字,变成了number类型的数字,就好了,所以说你们在用mongodb的时侯一定要注意储存数据的格式,
3、mongodb查询数据句子组织形式:
其实说白了就是limit和skip俩个函数的使用,但是具体的格式可的看好了,还有我这个是接受的参数,不过mongo的参数接受也好弄直接写就好了,不用象sql那样搞哪些${""}这种类型的,后面的sort函数说明了排序的方法,这里是设置的以ctime数组为标准,-1表示逆序,1表示乱序,
4、在本次代码编撰中,我首次使用了try catch 这个补错的形式,事实证明,还行,可以把时常的错误正常的复印下来,但是不影响代码的整体执行,或者是说下一次执行,整体觉得非常好,
具体的使用方式,在try中倒入你要执行的代码,在最后加上一行,throw Error();
然后给catch传入一个参数e,在catch中可以复印好多个信息,我只复印了其中的一个,e.message,
5、这次编码过程中主要用到了anync包,其中的ansyc.each循环,ansyc.waterfall执行完前面的才可以执行下边的,而且说谎给你下之间还可以从上至下传递参数,这个很重要,因为在本次编程中,每次获取的内容不同,每次代码执行的条件不同,即须要的参数也不同,即有可能下一次代码的执行就须要用到上一次代码执行得到的结果,所以说这个anync包,真的是值得研究,他的每位方式都不同,有时候可以得到意想不到的疗效。
6、在mysql中若果想要达到这样一个疗效,就是说,如果数据库中早已存在了,那就不予理会,或者说不重复储存,如果数据库中不存在,那么就储存进来,很简单,直接把插入数据的insert 换成 replace 。但是在mongodb中,应该是没有,或者说是我还没有发觉,我是那么解决的,定义了一个开关,令这个开关为真,每次储存之前,先把所有的数据循环一遍,看看有没有这条数据,如果有,让开关变为假,如果没有,继续执行,即判定此时开关的真伪,如果是真的,那就执行插入操作,如果是假的,就不予理会,这就达到了类似的疗效,否则每次就会储存大量的重复数据,
7、本次采集的核心,就是我文件中的common.js了,首先由于要采集,所以须要用到request包,采集到以后,要处理html格式的数据,使之可以使用类jquery的操作,那么久用到了cheerio这个包,然后在循环采集的时侯,会用到anync.each这个方式,所以会用到async这个包,
7-1、
通过搜狗陌陌采集,就要剖析搜狗陌陌的路径,每个公众号的页面的路径是这样的
%E8%BF%99%E6%89%8D%E6%98%AF%E6%97%A5%E6%9C%AC&ie=utf8&_sug_=n&_sug_type_=
这个是“这才是台湾”的页面的链接,经过剖析,所有的公众号的链接只有query前面的参数不同,但是query前面的参数是哪些呢,其实就是通过encodeURIComponent()这个函数转化以后的“这才是台湾”,所以说都一样,获取那种公众号,就将那种公众号的名子编码以后,动态的组合成一个链接,访问就可以步入到每位链接上面了,但是这个链接只是恳求到了这个页面,
并不是
这个页面,所以还的进一步处理,就是得到当前页面的第一个内容的链接,即href
当得到了这个链接,就会发觉他有他的加密方法,其实很简单的,就是在链接上面的加了三个amp;把链接上面的这三个amp;替换为空,就好了,这也就是第一步,得到每一个公众号的页面链接,
7-2
得到链接以后,就要进行访问了,即恳求,请求每位地址,得到每位地址的内容,但是每位页面显示的内容都不在页面中,即html结构中,在js中藏着,所以要通过正则匹配,得到整篇文章的对象,然后就循环每位公众号的这个对象,得到这个对象中的整篇文章的一些信息,包括title,thumb,abstract,URL,time,五个数组,但是我使用的代码烂透了,尽然当时使用了
对象.属性.foreach(function(item,index){
})
这种烂透了的形式,弄的最后好的在写一次循环才可以完全的得到每一个对象,否则只可以得到第一个,在这里应当用async.each,或者async.foreach这俩中形式每种都可以啊,而且都是非常好用的形式。这样的话买就得到了整篇文章的以上基本消息,
7-3、
第三个阶段,就是步入到整篇文章的详情页,获得整篇文章的内容,点赞数,作者,公众号,阅读量等数据,在这里遇到的主要问题是,人家的content直接在在js中,所有的img标签都有问题,他是以这些方式存在雨content中,但是这样的话,这样的图片在我们的网页中不能被显示,因为标签存在问题啊,html文档不认识这样的img标签啊,所以这儿要进行一些处理,把所有的用replace替换为