国家企业信用信息查询工商数据爬虫

国家企业信用信息公示系统采用了加速乐和极验的反扒,并且即使拿到了cookie后,获取所有详情也很费劲,每一部分数据都是一个请求,算下来一个公司少说也有三四十个请求才能完整地获取所有数据;

主要有5个cookie(__jsluid_h, __jsl_clearance, JSESSIONID, SECTOKEN, tlb_cookie)是多次请求结果运算得出的。
下面附请求步骤及源码:
1、第一次访问http://www.gsxt.gov.cn/index.html, 得到响应,HTTP状态码521,响应内容为混淆后的js代码:<script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('=')+((+true)+'')+......m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+((2^1)+'')+(6+'')+(~~{}+'')+((+[])+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>,处理字符串删掉=前和;后的代码,使用python js引擎执行该段代码会得到__jsl_clearance的值,__jsluid_h 的值在headers[‘Set-Cookie’]取得。
2。带着第一步算出来的两个cookies第二次访问http://www.gsxt.gov.cn/index.html, 得到响应,HTTP状态码521,响应内容为混淆后的js代码,使用正则处理后取得我们想要的代码段,加密算法有三种,sha1,sha256和md5,直接怼就行。
3,使用第二步算出的更新后的__jsl_clearance的值和第一步的__jsluid_h 的值第三次访问http://www.gsxt.gov.cn/index.html, 得到响应,HTTP状态码200,第三次请求的headers里会有我们想要的另外三个cookies:JSESSIONID, SECTOKEN, tlb_cookie,拼接好这5个cookie就可以访问拿数据了。下面附请求脚本,注意:全流程需要使用相同的代理ip,cookie和ip是有绑定的。

ex1 = re.compile(r'(?<=cookie=).+(?=;location.href)')
ex2 = re.compile(r'(?<=;go\().+(?=\)</script>)')


class GetJslCookie:
    """
    获取jsl_cookie,加速乐cookie与ip绑定
    传入调用类的代理,返回jslcookie和代理(如果代理过期有变化返回新代理,后续流程携带新代理进行请求)
    """

    def __init__(self, in_proxy):
        self.headers = {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,"
                      "*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7",
            "Cache-Control": "max-age=0",
            "Upgrade-Insecure-Requests": "1",
            "Referrer": "http://www.gsxt.gov.cn/index.html",
            "Host": "www.gsxt.gov.cn",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/86.0.4240.193 Safari/537.36"
        }
        self.pro = ProxyGenerator()
        self.proxy = in_proxy

    @staticmethod
    def get_hash(msg, flag):
        """jsl cookie 计算"""
        if flag == 'md5':
            md5 = hashlib.md5()
            md5.update(msg)
            return md5.hexdigest()
        elif flag == 'sha1':
            sha1 = hashlib.sha1()
            sha1.update(msg)
            return sha1.hexdigest()
        elif flag == 'sha256':
            sha256 = hashlib.sha256()
            sha256.update(msg)
            return sha256.hexdigest()
        else:
            raise Exception("get_hash flag err")

    def jsl_cookie(self, url):
        """
        需要进行两次请求才能获取到jsl的cookie
        :param url: url
        :return: None 函数中会对self.headers['cookie']进行赋值
        """
        for _ in range(5):
            try:
                if self.headers.get("cookie"):
                    del self.headers['cookie']
                logging.debug(f'第{_}次,jsl第一次请求,proxy={self.proxy}')
                rsp = RequestMethod.ip_requests(url, headers=self.headers, proxies=self.proxy)
                if rsp == -1:
                    self.proxy = self.pro.get_proxy()
                    logging.info(f"重新获取proxy={self.proxy}")
                    time.sleep(random.random() * 2)
                    continue

                first_js_code = re.findall(ex1, rsp.text)[0]
                js_ctx = execjs.compile(
                    "function cookie() {return " + first_js_code + ";}")
                cookie_1 = js_ctx.call("cookie") + ';' + rsp.headers.get('Set-Cookie')
                cookie_dict = {}
                for cook in cookie_1.split(';'):
                    if len(cook.split('=')) == 2:
                        k, value = cook.split('=')
                        cookie_dict[k.strip()] = value.strip()

                logging.debug('给第二次请求的headers构造cookie')
                __jsl_clearance = cookie_dict.get('__jsl_clearance')
                __jsluid_h = cookie_dict.get('__jsluid_h')
                self.headers['cookie'] = f'__jsl_clearance={__jsl_clearance}; __jsluid_h={__jsluid_h}'
                logging.debug(f'第{_}次,jsl第二次请求,proxy={self.proxy}')
                rsp = RequestMethod.ip_requests(url, headers=self.headers, proxies=self.proxy)
                if rsp == -1:
                    self.proxy = self.pro.get_proxy()
                    logging.info(f"重新获取1proxy={self.proxy}")
                    time.sleep(random.random() * 2)
                    continue

                if 'document.cookie' in rsp.text:
                    logging.debug("rsp.text 第二次还是521")
                    self.proxy = self.pro.get_proxy()
                    del self.headers['cookie']
                    continue
                __jsl_clearance = self.get_jsl_clearance(json.loads(re.findall(ex2, rsp.text)[0]))
                if __jsl_clearance:
                    logging.debug(f'第{_}次,获取__jsl_clearance成功')
                    return f'__jsl_clearance={__jsl_clearance}; __jsluid_h={__jsluid_h}', self.proxy
            except Exception as exp:
                self.proxy = self.pro.get_proxy()
                logging.error(f'获取__jsl_clearance异常--{exp},eline-{exp.__traceback__.tb_lineno}')

    def get_jsl_clearance(self, data):
        """获取jsl_clearance参数"""
        chars = data.get('chars')
        bts = data.get('bts')
        c_t = data.get('ct')
        h_a = data.get('ha')
        for chars_1 in chars:
            for chars_2 in chars:
                __jsl_clearance = bts[0] + chars_1 + chars_2 + bts[1]
                if self.get_hash(__jsl_clearance.encode('utf-8'), h_a) == c_t:
                    return __jsl_clearance
        return None


 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值