有读者让我爬逼乎,是我大意了...
前言
大家好,我是阿辰。
昨天折腾了很久的逼乎的爬虫,最后还是成功爬取到了相关的数据。
其实能够爬取到数据,用处有很多,看自己怎么用,但是kuls这里跟大家说千万别拿数据做盈利,不然小心进局子。
爬取数据就当提升自己的技术和见识吧。
逼乎思路
其实逼乎的爬虫有一些难度,尤其是对于js不是很熟悉的朋友,我在爬取过程中也是遇到了一些问题,最后也在百度上参考了一些大佬的思路才得以获取。
像这些大型网站js加密会经常性的更新和变化,所以了解思路就行,代码不是很重要。
也许你看这篇文章的时候,代码已经不管用了。
逼乎是需要登录的,登录的案例我就暂时不写了,如果在看数多,之后也分享给大家!
除了自动登录,我们也可以使用cookie的方式来进行登录。
我们先登录逼乎,然后搜索一个关键词,打开调试器。
获取cookie,我们点进Network调试,然后过滤doc文件,就会看到过滤出一个包,然后点开就能够看到cookie了。
有了cookie,登录的问题就解决了。
登录解决后,我们就需要找到获取数据的接口了。
https://www.zhihu.com/api/v4/search_v3?t=general&q=%E6%89%8B%E6%9C%BA&correction=1&offset=0&limit=20&lc_idx=0&show_all_topics=0
我们可以先按照平时的思路来进行爬取,首先就是把Request Headers中的信息给提取出来,编写我们的header。
然后直接带着cookie请求。
我们会发现我们是可以正常获取的。
但是当我们去换一个关键词搜索时,就会返回一个error的信息。
headers = {
'User-Agent': User_Agent,
'cookie': cookie,
'referer': referer,
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.52',
'x-zse-83': '3_2.0',
'x-zse-86': '1.0_%s' %encrypt_str
}
通过简化headers里的内容,我们可以把它简化成如上所示。
其中,最为关键的就是x-zse-86,这是逼乎的一个加密算法,想要爬取逼乎必须要去对这个加密进行了解。
那么,怎么去破解x-zse-86算法呢?
首先,我们要去找相关的js代码。对于这类加密的玩法,我们都需要第一步去找js,怎么找呢?
这里也提供几个思路,第一个右击网页->查看源代码,有一些加密会在html页面当中,例如下图:
但是,如果你去右击逼乎的源码,你会发现不太好找啊!
此时,我们应该动用第二个思路,前往控制台的source,可以查看到该网站相关的文件。
具体是哪个js文件,大家具体可以看我上面的图片。
通过搜索x-zse-86关键词,我们会发现它由"1.0"+"_"+p 来组成的。
c.set("x-zse-86", "".concat("1.0", "_").concat(p)),
也就是说,我们现在只要弄清楚了p变量是啥,然后获取它就能够拿到x-zse-86的值。
通过观察,我们会发现p变量是等于f.signature的。于是我们就通过搜索signature来看看到底是什么。
在上图中,我们找到了signature的值。
我们会发现它是通过几个函数来得到的。
signature: V()(B()(f))
既然这么多层,我们只能一层一层来扒了。
首先是f
f = [r, u, l, o, X(d) && d, i].filter(Boolean).join("+");
我们往上面看代码,会发现f就是由上面几个值拼凑而成的。
通过断点debug(关于断点不懂的,可以百度或者加我好友进行讨论),我们发现f拼凑出来的几个变量的值分别是什么。
其实就是headers里的x-zse-83+url+referer+“cookie.d_c0”
f解决了,我们需要解决一下B是啥了。
这里我们可以通过在控制台中调用这个B方法,来看看它输出的是什么:
可以发现它输出了一串字符,经过简单的分析,我们将一串带有url等信息作为参数传入B方法,然后返回出另外一串字符。
作为程序员,我们接触的最常见的加密就是md5,所以我们拿之前断点的f值去进行加密
果不其然,我们拿到的值跟输出的是一模一样的。
B方法也解决了,就是一个md5加密。最后我们来讲解一下V函数:
照样打断点:
跳一次
我们会发现这是一个加密的算法
var b = function(e) {
return __g._encrypt(encodeURIComponent(e))
};
通过在console控制台中简单的执行相关函数,我们会发现__g._encrypt的处理方法就是这句话的上面一部分js代码,由于代码过多,这里就不展示出来,会在底部告知大家。
这就很好说了,执行这个js加密算法,我们需要通过调用Python来调用js的代码。这时我们会采用jsdom的方式来执行。
jsdom的安装:
npm i jsdom -g
结尾
整体的思路就说完了,如果你觉得本文对你有所帮助,麻烦点个在看呀!
如果大家对本文代码源码感兴趣,公众号后台回复:逼乎 ,获取完整代码!
推荐阅读