Python爬虫遇到YunSuoAutoJump跳转网页
最近在搞一个自制的参考文献归档,查阅记录的工具。需要刚好需要用到Python爬虫,爬取Paper和References。国内由于谷歌学术无法访问,所以怕一个国内的网站,但基本就是一个国内的代理服务器,文献是结果一样的。不过在爬取过程过遇到了网址跳转的问题。
前情提要
在使用requests库爬取关键词时,返回来的并不是用浏览器获得的结果。
例如我们一般爬取搜索页面,输入参数seismic,通过Fiddler抓包发现网址是
http://so.hiqq.com.cn/scholar_complete.php?q=seismic&hl=zh-CN&as_sdt=0%2C5&btnG=
但是我们调用Requests库去Get请求,返回的不是想要的内容,而是
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Thu, 13 Feb 2020 13:54:15 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Location: https://zz.glgoo.top/scholar?hl=zh-CN&as_sdt=0%2C5&q=seismic&btnG=
响应报文里没有响应体,头文件里就是一个类似重定向的东西,告诉我们,去这个Location找。这个倒是不难,直接再Request这个Location
过程
结果几次的摸索,算是搞清楚了整个过程,我以最一般的情况来说(不带有任何Cookies)。
一、给出Location
猜测是这个代理服务器存在很多个,域名基本都是
xxx..glgoo.top/scholar
xxx.gufenxueshu.com/scholar
每次都需要在kuaisou里给你一个门的钥匙。我们直接将此次Location的变量传给下一个Request
二、传递security_id
对xxx.fufenxueshu.com/scholar的访问,首先会检测有没有Cookies,主要有4个参数
UM_distinctid
_gads
security_session_verify
security_session_mid_verify
前两个浏览器里可以直接获取,后两个,如果没有携带,则会分两次传递过来。本次Request获得了security_id,通过定义一个函数来获取参数并传递给下一个请求。
1 | def getssv(self,str): |
三、获取security_mid_id
原理同上,不过这次请求需要带上上次给的ssv,同时,访问的站点后缀发生了一些变化。由于上次传来的响应体还包含了一个YunSuoAutoJump
1 |
|
分析不难发现,其实就是获取屏幕的分辨率(除去下方的任务栏),例如‘(1920,1080)’再通过一个函数,转化为十进制,我们写一个这样的转化函数。
1 | def stringToHex(self,string): |
后面只需要在原来的url后面加上
&security_verify_data=stringToHex(1920,1080)
就可以获得ssmv了。
四、获取真正目标html
在拿到两个认证Id后,添加到Cookies里,再回过头来访问原始url就可以正常拿到想要的html了。
简化
## 认证上的简化
其实在后续的请求中,发现有时候不需要ssv和ssmv也可以拿到完整的html,为了保持程序的完整性和速度,我们加一个判断就可以了,如果获取的ssv为空,就直接把这个request丢到beautifulsoup里,不用再去获取ssv和ssmv了。
Location上的简化
另外,其实在第一步获取Location时也可以省略,直接拿一个固定的服务器,不过这样的结果就是,如果这个服务器访问量太大,需要你刷新一下或者排队,也就是再次request一次。两种方法无非就是
- 固定花费一定时间来到一个通畅的道路
- 不花费时间来到一个固定的道路,不过这个道路可能会堵塞
预告
其实本次爬虫主要是为了一个自制的文献管理和记录的工具,后续我们会继续在PyQt中使用到这个类,完成我们对Paper和References的获取与记录。
Comments