【Python爬虫实例】Python解决521反爬方案

390 篇文章 2 订阅
276 篇文章 4 订阅

写在前面的话

Python在爬虫方面的优势,想必业界无人不知,随着互联网信息时代的的发展,Python爬虫日益突出的地位越来越明显,爬虫与反爬虫愈演愈烈。下面分析一例关于返回HTTP状态码为521的案例。

(全套教程文末领取哈)

案例准备

案例剖析

1) 浏览器访问【“一带一路”建设成果图鉴丨陆海内外联动,湖北推动产能合作纵深推进】

img

2)写ython代码访问,查看http(s)返回状态

# coding:utf-8


import requests
from fake_useragent import UserAgent


USER_AGENT = UserAgent()
ua = USER_AGENT.random
url = r'https://www.yidaiyilu.gov.cn/xwzx/gnxw/87373.htm'
headers = {
    "Host": "www.yidaiyilu.gov.cn",
    "User-Agent": ua
}
rs = requests.session()
resp = rs.get(url)
print(resp.status_code)
print(resp.text)

不幸的是,返回的http的状态码却是501text为一段混淆的js代码。

img

python_anti_spider_521_requests_20190505.png

3)百度查资料,推荐为文首的【参考文献】

继续参照资料修改代码,Python执行JS首选execjspip安装如下:

pip install PyExecJS

将请求到的js执行:

text_521 = ''.join(re.findall('<script>(.*?)</script>', resp.text))
func_return = text_521.replace('eval', 'return')
content = execjs.compile(func_return)
print(content.call('f'))

将返回的结果print发现还是一段JS,标准格式化(【格式化Javascript工具】),结果如下所示:

var _2i = function () {
        setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
        document.cookie = '__jsl_clearance=1557019601.296|0|' + (function () {
                    var _2i = [([(-~[] << -~[])] * (((+!+{}) + [(-~[] << -~[])] >> (-~[] << -~[]))) + []), (-~{} + [] + [
                                []
                            ][0]) + [3 - ~(+!+{}) - ~(+!+{})], (-~{} + [] + [
                                []
                            ][0]) + [5], (-~{} + [] + [
                                []
                            ][0]) + [~~''], (-~{} + [] + [
                                []
                            ][0]), [-~~~!{} + [~~
                                []
                            ] - (-~~~!{})], (-~{} + [] + [
                                []
                            ][0]) + [-~{} - ~[-~{} - ~{}]], (-~{} + [] + [
                                []
                            ][0]) + (-~{} + [] + [
                                []
                            ][0]), [-~(+!+{})], (-~{} + [] + [
                                []
                            ][0]) + ([(-~[] << -~[])] * (((+!+{}) + [(-~[] << -~[])] >> (-~[] << -~[]))) + []), (-~{} + [] + [
                                []
                            ][0]) + (-~[-~{} - ~{}] + [
                                []
                            ][0]), (((-~[] << -~[]) << (-~[] << -~[])) + [
                                []
                            ][0]), [3 - ~(+!+{}) - ~(+!+{})], (-~{} + [] + [
                                []
                            ][0]) + (((-~[] << -~[]) << (-~[] << -~[])) + [
                                []
                            ][0]), [5],
                            [-~{} - ~[-~{} - ~{}]], (-~{} + [] + [
                                []
                            ][0]) + [-~(+!+{})], (-~[-~{} - ~{}] + [
                                []
                            ][0]), [~~'']
                        ],
                        _1d = Array(_2i.length);
                    for (var _5 = 0; _5 < _2i.length; _5++) {
                        _1d[_2i[_5]] = ['Bz', (-~[-~{} - ~{}] + [
                                    []
                                ][0]), [{} + [] + [
                                    []
                                ][0]][0].charAt(-~~~!{}), 'DR', ([(-~[] << -~[])] / (+!/!/) + [] + [
                                    []
                                ][0]).charAt(-~[-~~~!{} - ~(-~[] - ~{} - ~{})]) + (+[(+!+{}), (+!+{})] + []).charAt((+!+{})), [
                                    [][
                                        []
                                    ] + [] + [
                                        []
                                    ][0]
                                ][0].charAt(-~{} - ~[-~{} - ~{}]), 'qM', (((-~[] << -~[]) << (-~[] << -~[])) + [
                                    []
                                ][0]) + (+[(+!+{}), (+!+{})] + []).charAt((+!+{})) + (-~{}
                                    /~~''+[]+[[]][0]).charAt((+!/!/)),'S','g%',(((-~[]<<-~[])<<(-~[]<<-~[]))+[[]][0]),'HxXL',[[][[]]+[]+[[]][0]][0].charAt(-~{}-~[-~{}-~{}]),'D',[-~(+!+{})],'T%','YW',[{}+[]+[[]][0]][0].charAt(-~~~!{}),'vw'][_5]};return _1d.join('')})()+';Expires=Sun, 05-May-19 02:26:41 GMT;Path=/;
                                    '};if((function(){try{return !!window.addEventListener;}catch(e){return false;}})()){document.addEventListener('
                                    DOMContentLoaded ',_2i,false)}else{document.attachEvent('
                                    onreadystatechange ',_2i)}

4)修改与浏览器相关的代码,然后放入浏览器的console进行调试。

img

python_anti_spider_521_js_debug_20190505.png

注意,在调试过程中,不难发现,js变量是动态生成的。最初还嵌套有document.createElement('div')Pythonexecjs包不支持处理这类代码,需要做相应处理。

5)综上分析,完整代码如下:

#!/usr/bin/env python
# coding:utf-8


import sys
import re
import requests
import execjs
from fake_useragent import UserAgent


reload(sys)
sys.setdefaultencoding('utf8')


class YiDaiYiLuSpider(object):
    """
    中国一带一路网(521反爬)
    """

    USER_AGENT = UserAgent()
    ua = USER_AGENT.random
    url = r'https://www.yidaiyilu.gov.cn/xwzx/gnxw/87373.htm'
    headers = {
        "Host": "www.yidaiyilu.gov.cn",
        "User-Agent": ua
    }

    @classmethod
    def get_text521(cls):
        """

        :return:
        """

        rs = requests.session()
        resp = rs.get(url=cls.url, headers=cls.headers)
        text_521 = ''.join(re.findall('<script>(.*?)</script>', resp.text))
        cookie_id = '; '.join(['='.join(item) for item in resp.cookies.items()])
        return cookie_id, text_521

    @classmethod
    def generate_cookies(cls, func):
        """

        :param func:
        :return:
        """

        func_return = func.replace('eval', 'return')
        content = execjs.compile(func_return)
        eval_func = content.call('f')
        var = str(eval_func.split('=')[0]).split(' ')[1]
        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').\
            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), '')

        content = execjs.compile(mode_func)
        cookies_js = content.call(var)
        __jsl_clearance = cookies_js.split(';')[0]
        return __jsl_clearance

    @classmethod
    def crawler(cls):
        """

        :return:
        """

        url = r'https://www.yidaiyilu.gov.cn/zchj/sbwj/87255.htm'
        cookie_id, text_521 = cls.get_text521()
        __jsl_clearance = cls.generate_cookies(text_521)
        cookies = "{0};{1};".format(cookie_id, __jsl_clearance)
        cls.headers["Cookie"] = cookies
        print(cls.headers)
        res = requests.get(url=url, headers=cls.headers)
        res.encoding = 'utf-8'
        print(res.text)


if __name__ == '__main__':

    YiDaiYiLuSpider.crawler()

运行结果如下:

img

关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

朋友们如果需要这份完整的资料可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

一、Python学习大纲

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、Python必备开发工具

在这里插入图片描述

三、入门学习视频

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。在这里插入图片描述

五、python副业兼职与全职路线

在这里插入图片描述

在这里插入图片描述

👉[[CSDN大礼包:《python兼职资源&全套学习资料》免费分享]]安全链接,放心点击

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值