【已解决】如何用selenium优雅解决反爬导致的521报错,不!用!管js加密Cookie

问题

如题,爬取一带一路政府官网的时候,遇到了521报错。一查发现是js加密的问题。

该网站反爬原理,用我并不专业的语言描述如下:要求访问两次这个网站,第一次的时候会得到(Cookie和)一个js函数,这个函数执行之后会得到Cookie,第二次访问就利用这个Cookie来进行请求。

但大家也看到了,我的标题中是一个愤愤不平的“不管”。那么以下是我的心路历程。

解决

绕了很多弯路在解决js加密的问题上,企图解密js,获得js函数,然后通过python的execjs库来执行函数。然后遇到了很多问题,主要原因是这里的函数并不简单,有些地方execjs是不能解决的。

但后来缝缝补补之下也找到了方法,这里直接贴代码,有需要的朋友可以参考:

def crawler(CurrentRootURL):
    print("开始>>>" + CurrentRootURL)
    ua = UserAgent().random
    headers = {
                'Host': 'www.yidaiyilu.gov.cn',
                'Referer': 'https://www.yidaiyilu.gov.cn/info/iList.jsp?cat_id=10149',
                'User-Agent': ua,
    }
    rs = requests.session()  #可以全局使用Cookie
    resp = rs.get(CurrentRootURL,headers=headers)
    txt_521 = ''.join(re.findall('<script>(.*?)</script>', resp.text))
    cookie_id = '; '.join(['='.join(item) for item in resp.cookies.items()])

    #编译生成cookie的js函数
    func_return = txt_521.replace('eval', 'return')
    content = execjs.compile(func_return)
    eval_func = content.call('f')
    #var = str(eval_func.split('=')[0]).split(' ')[1]
    var = re.findall('var (.*?)=',eval_func)[0]
    rex = r">(.*?)</a>"
    rex_var = re.findall(rex, eval_func)[0]
    mode_func = eval_func.replace('document.cookie=','return ').replace(';if((function(){try{return !!window.addEventListener;}', ''). \
        replace("catch(e){return false;}})()){document.addEventListener('DOMContentLoaded'," + var + ",false)}",''). \
        replace("else{document.attachEvent('onreadystatechange'," + var + ")}",''). \
        replace(r"setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')',1500);",''). \
        replace('return return', 'return eval'). \
        replace("document.createElement('div')",
                '"https://www.yidaiyilu.gov.cn/"'). \
        replace(r"{0}.innerHTML='<a href=\'/\'>{1}</a>';{0}={0}.firstChild.href;".format(var, rex_var), '')
	#执行js函数,获得Cookie
    content = execjs.compile(mode_func)
    #print(mode_func)
    cookies_js = content.call(var)
    __jsl_clearance = cookies_js.split(';')[0]
    cookies = "{0};{1};".format(cookie_id, __jsl_clearance)
    headers["Cookie"] = cookies
    res = requests.get(CurrentRootURL, headers=headers)
    HTMLText = res.text
    return HTMLText

如此,便可以访问网站了。

主要参考了博文:
爬虫遭遇状态码521陷阱 破解js加密cookie
然后还有一篇,也是爬取一带一路官网的博文,但是刚刚没有找到网址,大家可以再搜一搜,

但是!!!

这并不是我今天的重点!

我的重点是,后来直接在某篇博文的评论区发现了一个方法:

`options = webdriver.ChromeOptions()
        options.add_experimental_option('excludeSwitches', ['enable-automation']) # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
        self.browser = webdriver.Chrome(executable_path=chromedriver_path, options=options)
        self.wait = WebDriverWait(self.browser, 10) #超时时长为10s
        self.browser.get(self.url) # 这次返回的是 521 相关的防爬js代码
        self.browser.get(self.url) # 调用2次 self.browser.get 解决 521 问题 
        html = self.browser.page_source
        print(html)`

What???用selenium竟然如此简单????

但仔细一想,没毛病啊,网页要求我访问两次,那我就模拟浏览器访问两次呗。

没什么,就是写出来分享一下,纪念我逝去的头发。

总结

1.还是一个道理:多看评论区。
2.怎么反爬,就怎么爬。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值