2019-12-10 爬网页9-绕过Selenium检测

天涯浪子 提交于 2019-12-11 02:16:21

爬Boss直聘网站https://www.zhipin.com/job_detail/?query=js&city=101020100&industry=&position=,发现无法获得信息,获得html的title是“请稍后”,页面显示的是“正在加载中…”。

检查后发现原来是要验证cookie的,关键就是__zp_stoken__字段。
具体过程可以在火狐里跟踪到。

地址栏中输入https://www.zhipin.com/job_detail/?query=js&city=101020100&industry=&position=后,会发现会得到响应https://www.zhipin.com/web/common/security-check.html?seed=/VA4nRzK5Ai5Witwwefvzvj4WXlCwIK7isBb/pi+oPQ=&name=af570efa&ts=1575981514326&callbackUrl=/c101210100/?query=js&city=101020100&industry=&position=,也就是重定向到security-check.html,这里还有几个参数seed,name,ts。

现在来观察security-check.html代码,其实它就是我在爬虫中得到返回的html页面。

<title>请稍后</title>
<p class="gray">正在加载中...</p>

再往下看

 var url = window.location.href;
                    var seed = decodeURIComponent(getQueryString("seed")) || "";
                    var ts = getQueryString("ts");
                    var fileName = getQueryString("name");
                    var callbackUrl = decodeURIComponent(getQueryString("callbackUrl"));
                    var srcReferer = decodeURIComponent(getQueryString("srcReferer")||'');
                    
                    if (seed && ts && fileName) {
                        seriesLoadScripts("security-js/" + fileName + ".js", function() {
                            var expiredate = new Date().getTime() + 32 * 60 * 60 * 1000 * 2;
                            var code = "";
                            var nativeParams = {};
                            var ABC = window.ABC || frame.contentWindow.ABC;
                            try {
                                code = new ABC().z(seed, parseInt(ts)+(480+new Date().getTimezoneOffset())*60*1000);
                            } catch (e) {}
                            if (code && callbackUrl) {
                                Cookie.set("__zp_stoken__", code, expiredate, COOKIE_DOMAIN, "/");
                                // 据说iOS 客户端存在有时写cookie失败的情况,因此调用客户端提供的方法,交由客户端额外写一次cookie
                                if (typeof window.wst != "undefined" && typeof wst.postMessage == "function") {
                                    nativeParams = {
                                        name: "setWKCookie",
                                        params: {
                                            url: COOKIE_DOMAIN,
                                            name: "__zp_stoken__",
                                            value: encodeURIComponent(code),
                                            expiredate: expiredate,
                                            path: "/"
                                        }
                                    };
                                    window.wst.postMessage(JSON.stringify(nativeParams));
                                }

我们刚才看到的参数seed ,name和ts都出现了。
这里还出现了一个js文件,“security-js/” + fileName + “.js”,它的名字是动态的,上面响应的链接中已经有了name=af570efa。
最后也是最重要的,代码中设置了一个cookie,zp_stoken,期限是64小时,值来自上面的那个动态名称的js文件。

继续观察af570efa.js文件,这个应该是加密的,我没有办法了解里面写了什么,也无法知道__zp_stoken__的生成逻辑。

由于在浏览器里直接打开这个链接是可以正常显示查询结果。
所以现在思路就是通过selenium模拟登录,获得cookie,然后再爬。

但是程序里用selenium模拟浏览器后依然失败,无法打开网页。
查了网上,原来可能是被反扒机制检测出来的,我没有找到相关js,猜测可能是被加密了(就是在那个af570efa.js文件中)。

继续查攻略,只有模拟chrome可以避免被检测的方案,我用的是火狐,没有对应方案。

不得已,下载chrome,然后再下载对应版本的chromedriver,http://npm.taobao.org/mirrors/chromedriver/。注意,放置chromedriver的目录必须在环境变量path中。相关配置参见https://blog.csdn.net/weixin_42555985/article/details/103047764。

后面就简单了,加入以下代码。
我偷懒,直接把chromedriver.exe放在火狐目录中了,因为火狐在path中。

chromedriver_path = 'C:\Program Files\Mozilla Firefox\chromedriver.exe' 
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome(executable_path=chromedriver_path, options=options)
driver.maximize_window() 
url="https://www.zhipin.com/job_detail/?query=js&city=101020100&industry=&position="

driver.get(url)
time.sleep(5)

# 获得 cookie信息
cookie_list = driver.get_cookies()
print cookie_list[len(cookie_list) -1] #__zp_stoken__
driver.quit()

运行后终于可以打开链接,得到cookie了,特别是那个关键的__zp_stoken__。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!