欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

wordpress地址出现 /?security_verify_data=313932xxx原因及解决办法 有大用

511遇见

防护策略从中降到最低,再查看浏览记录就恢复正常了,如果你也在使用云锁,希望对你有帮助。

511遇见


发布日期: 

所属分类: Wordpress 综合 标签: 


来自  http://www.511yj.com/wordpress-security-verifydata.html



啥是云锁

云锁其实是个服务器安全软件,主业也不是反爬虫,不过有一条是可以防止cc攻击,而爬虫行为就像是频次不高的cc攻击,因而直接请求目标站并不能返回目标内容。
最近正好做了个需求抓取 中国土地市场网 上的一些信息,这个网站刚好就使用了云锁。

云锁如何反爬虫

也没有多高明,无非就是常用的:

  1. 封禁高频IP

  2. 放个cookie
    第一个好解决,自己做个高匿代理池就行
    这里推荐Cithub上一个老哥的代码很好用:https://github.com/qiyeboy/IPProxyPool
    关键是第二项 cookie 网站需要几个cookie, cookie如何生成(本地还是服务端)

筛选cookie

这里不采用浏览器分析cookie 是因为浏览器一访问会有很多js 生成的本地cookie, 直接代码请求比较清爽直观

  1. 因为一般携带cookie的方式都是 3xx 跳转先放一个cookie 之后携带该cookie 请求得到正常页面所以二话不说 先requests 禁止跳转走一波:
    运行之后发现是js执行的跳转并不是服务器返回3xx跳转,所以无需指定是否跟随跳转

if __name__ == '__main__':
   resp = requests.get("http://www.landchina.com/", timeout=5)
   print("info:")
   print(resp.text)
   print("cookies:")
   for key, value in resp.cookies.items():
       print(f"key: {key} value: {value}")

仔细观察发现请求返回的html结果中有如下代码

function stringToHex(str) {
       var val = "";
       for (var i = 0; i < str.length; i++) {
           if (val == "") val = str.charCodeAt(i).toString(16); else val += str.charCodeAt(i).toString(16);
       }
       return val;
   }

   function YunSuoAutoJump() {
       var width = screen.width;
       var height = screen.height;
       var screendate = width + "," + height;
       var curlocation = window.location.href;
       if (-1 == curlocation.indexOf("security_verify_")) {
           document.cookie = "srcurl=" + stringToHex(window.location.href) + ";path=/;";
       }
       self.location = "/?security_verify_data=" + stringToHex(screendate);
   }
   setTimeout("YunSuoAutoJump()", 50);

原来是执行了 YunSuoAutoJump() 这个方法生成了个跳转链接
就是使用dom方法获取浏览器长宽再进行哈希变换再执行跳转:
self.location = "/?security_verify_data=" + stringToHex(screendate);
上述请求返回携带的cookies:
key: yunsuo_session_verify value: 2972e332b013f2963dc1ca74531a44b6
2. 二话不说带上cookie, 拼接个跳转链接再请求一下,代码修改如下:
这里可以注意到哈希函数是固定的而浏览器的长宽也可以使固定的,所以我们可以不用研究哈希函数直接使用固定的stringToHex(screendate) 结果就行, 自己用浏览器访问一下就能得到结果

if __name__ == '__main__':
   url = "http://www.landchina.com/"

   resp = requests.get(url, timeout=5)
   cookie = {}
   for key, value in resp.cookies.items():
       cookie[key] = value

   resp = requests.get(
       '{}{}'.format(url, '?security_verify_data=313932302c31303830'),
       cookies=cookie
   )

   print(resp.text)
   
   for key, value in resp.cookies.items():
       cookie[key] = value
       print(f'{key}: {value}')

html 内容和第一次请求一样依旧不是正确结果,不过又返回了一个cookie:
security_session_mid_verify: b621fcf2ed74e709c200e2af37eada46
3. 看来还要再携带返回的cookie进行一次请求,修改代码如下:

if __name__ == '__main__':
   url = "http://www.landchina.com/"

   resp = requests.get(url, timeout=5)
   cookie = {}
   for key, value in resp.cookies.items():
       cookie[key] = value

   resp = requests.get(
       '{}{}'.format(url, '?security_verify_data=313932302c31303830'),
       cookies=cookie
   )

   for key, value in resp.cookies.items():
       cookie[key] = value

   # 注意这里的cookie字典中存有第一次请求得到的 yunsuo_session_verify,和第二次请求得到的 security_session_mid_verify
   resp = requests.get(
       url,
       cookies=cookie
   )

   print(resp.status_code)
   print(resp.text)

这时我们发现返回的就是我们想要的结果了,至此完成整个云锁反爬的反反爬工作

代码封装和后续

封装如下

import requests


def get_cookies(url, proxies):
    proxies = {'http': 'http://{}'.format(proxies), 'https': 'http://{}'.format(proxies)}
    return {
        'yunsuo_session_verify': requests.post(url, proxies=proxies).cookies.get('yunsuo_session_verify'),
        'security_session_mid_verify': requests.post('{}{}'.format(url, '&security_verify_data=313932302c31303830'), proxies=proxies).cookies.get('security_session_mid_verify')
    }

def get_proxy():
	# 大规模爬取要增加代理,这里是伪代码啦
	return prox

if __name__ == '__main__':
	url = '你要抓取的url'
	prox = get_proxy()
	cookie = get_cookies()
	resp = requests.get(
        url,
        proxies=proxies,
        cookies=cookie
    )
    # 做你想做的吧

一些需要注意的事:

  1. 网站返回的cookie 是根据访问的ip进行计算的,所以三次请求使用的代理要是一个

  2. 这里只是个简单demo, 如果需要大规模抓取最好还是用redis + 固定代理 实现一个 cookies池,异步维护每个ip对应的cookies,这样实际抓取的流程就是:获取一个ip代理 -> 根据代理ip得到对应的cookies -> 使用该代理 + cookies 进行抓取,这样可以减少抓取的请求数提升速度

  3. 如果是大规模爬取可以使用 aiohttp 进行改写,原理相同,这里文章为了方便使用requests进行示意
    转载注明出处,欢迎留言探讨


来自  https://blog.csdn.net/baidu_36146918/article/details/89928154

普通分类: