最近看到一篇【猿人学Python】文章【写爬虫,免不了要研究JavaScript设置cookies的问题 】,里面说到了mps“zggaw“的破解返回521的问题,然后自己也去尝试了一把,现在把我的实现过程分享出来,让有需要的人看到。
那我们就直接入正题了,首先我们的目标网址是“http://www.mps.gov.cn/n2253534/n2253535/index.html”,我们直接发起请求试试:
很明显,看到返回521,返回状态码521是什么意思呢?
5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
这时候我们打开Chrome的开发者工具,到Network模块,一定把Preserve log 打上勾不然看不到521那个红色的失败链接,Preserve log的作用是保留请求日志。跳转页面的时候勾选上,可以看到跳转前的请求。
然后点开那个红色的index.html,可以看到它status_code状态码为521,下面set cookie 设置了cookie值,切换到Response发现没有内容,为空。
这时候可以尝试两种方法继续走下去:
第一种就是尝试用火狐浏览器重复上面操作,查看Response响应栏下是否有内容
第二种就是直接尝试r.text,看是否有内容返回
可以看到,上面两种方法都能得到一串js代码,给了你走下去的可能,还有你们也可以通过抓包工具来获得这些内容。
得到了一串js代码,我们应该怎么办了?首先,这一串看着就不舒服,我们先把它格式化了再看,介绍一个js代码美化网站“https://beautifier.io/”,当然还有很多网站可以美化js代码,自行百度即可。那么接下来我们把代码拷贝到这个网站下进行查看。
选取我们需要的部分< script> < /script>中间的那一部分,并做修改复制到Chrome开发者工具的Console模块进行调试,把eval换成console.log(下面代码已经修改),并拷贝到Console之后enter即可。
可以看到下面红框中又返回了一段js代码,这时候别着急,继续我们之前的,先把它格式化美化了再说
复制拷贝代码到上面的js代码美化网站中,进行美化查看
这个时候可以看到一段很长的js代码,我们慢慢分析,找出我们想要的setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
开头代码中可以看到1500估计就是我们一开始进去是等待网站在刷新出现内容的那一点五秒,这不重要,我们继续往下看document.cookie = '__jsl_clearance=1562764375.435|0|' + (function() {
下一句就是我们想要的了,cookie关键词,我们爬虫无非就那几样东西,到这里大概能知道就是这个网站会返回一串生成cookie值的js代码,然后需要携带上这串js去请求网站就能成功返回信息了。我们找找cookie值的生成代码部分:
上面就是我们需要的,把他复制到Console调试查看下调试结果是否我们所需要的
根据调试结果我们知道,没错我们找对了,这就是我们需要的cookie的js生成代码,接下来就很简单了,我们用python把这过程重现一遍,用python的js代码运行模块(PyV8、PyExecJS、js2py,推荐使用PyExecJS)运行这几段js代码得到我们所需cookie就可以携带者cookie去登陆网站了,那么我们开始实现python代码吧!
首先,我这次用到了execjs这个模块,你需要pip安装pip install PyExecJS
,然后导入即可import execjs
我安装了nodejs,所以我机器中execjs运行js代码的后端如上图所示。
然后就是我通过requests.Session()
构造session发起请求并且这样方便管理cookies,发起请求代码res = session.get(url, headers=headers)
。返回结果我们也知道就是一段js代码,然后我们需要处理这段js代码,用python语句实现我们之前做的,目标是得到cookie的值。
处理返回js代码块python语言实现如下:
代码中已经注释很清楚了,自己理解理解。
这时候已经得到cookie那个值了,下面就是构造cookie并携带发起请求就可以,相信这对于你们来说很简单。
等等,你以为就结束了吗,其实在这个过程中,我还发现一个问题就是,我是通过parse_qsl处理的cookie返回值,但是parse_qsl会把 字符串 unquote,但是发给服务器的cookie的__jsl_clearance 最后面的|后面的字符串必须是quote过的服务器才认为正确,所以我们还要在进行一步处理,或则也可以直接分割,先按分号:分割,再按等号=分割就可以,这就便面了接下来这一步。
好的,到这里就基本完成了js_cookie的破解了,你也可以毫无问题的请求这个网站不会再遇到521问题了,是不是解决了,最后提醒一下,因为他返回的js计算出来的cookie值那个cookie最前面是一个时间戳,跟实际时间比差7小时,所以你懂得,处理时间戳时再加上7小时(也就是25200秒)即可。
到这里,本篇文章也完成了写作,不知不觉也写了9000多字,希望文章能帮到有需要的你们,如果想要完整代码,关注公众号【离不开的网】发送“mps_js_cookie”即可,避免编写错误,建议你直接拷贝黏贴。