当前位置: 萬仟网 > IT编程>脚本编程>Python > Python爬虫:某网站cookie参数__jsl_clearance_s生成分析

Python爬虫:某网站cookie参数__jsl_clearance_s生成分析

2020年11月19日  | 萬仟网IT编程  | 我要评论
逛论坛发现一个求助帖,想获取数据但网站有cookie反爬,闲来无事就分析了一下cookie参数生成方法~目标:生成cookie中的__jsl_clearance_s参数工具:chrome/firefox浏览器、fiddler、pychram、python3.7、解混淆专解测试版V0.1模块:requests、re、execjs、json分析:首先打开浏览器,和fiddler抓包工具,发现浏览器进行了三次请求,前两次响应的状态码为521,响应内容都是一段js代码,第三次请求响应得到正常内

逛论坛发现一个求助帖,想获取数据但网站有cookie反爬,闲来无事就分析了一下cookie参数生成方法~

目标:生成cookie中的__jsl_clearance_s参数

工具:chrome/firefox浏览器、fiddler、pychram、python3.7、解混淆专解测试版V0.1

模块:requests、re、execjs、json

分析:

首先打开浏览器,和fiddler抓包工具,发现浏览器进行了三次请求,前两次响应的状态码为521,响应内容都是一段js代码,第三次请求响应得到正常内容,并且携带了两个cookie参数;
图1
在这里插入图片描述
通过三次请求对比,发现第三次请求cookie中的__jsl_clearance_s参数和第二次请求中的并不一样;
先看看第一次响应的结果,为一段js,这段js代码为浏览器设置了一个cookie;
图2
这里直接利用正则将这段代码提取出来,再利用execjs模块执行,即可得到这个cookie,当然这个cookie并不是最终的cookie;

# 提取js代码
js_clearance = re.findall('cookie=(.*?);location.href=', response.text)[0]
# 执行后获得cookie参数js_clearance
result = execjs.eval(js_clearance).split(';')[0]

通过观察第二个请求,第二个请求再次得到一段js代码,并且携带了两个cookie参数,一个__jsluid_s、一个__jsl_clearance_s,而__jsl_clearance_s就是刚刚利用js生成的,所以和第三次请求的__jsl_clearance_s不一样,__jsluid_s是第一次请求后服务器为浏览器设置的;
图3
图4
继续分析得知第二次请求需要携带这两个cookie参数才能得到第二段js代码。这段js代码是混淆过的,利用解混淆专解测试版V0.1进行解混淆,得到正确的js代码(js代码就不放出来了);
简单解读cookie生成方法就是调用go方法并传入一段参数,最后该方法为浏览器设置一个cookie。那么思路就简单了,直接将js代码保存为本地文件,利用execjs模块执行代码调用go方法并传入需要的参数就能得到cookie;不过需要修改一下js代码,先将js代码中go方法调用删除再将为浏览器设置cookie的代码修改为直接返回;

setTimeout(function () {
      document["cookie"] = _0x1c7f44["tn"] + "=" + _0x3227c3[0] + ";Max-age=" + _0x1c7f44["vt"] + "; path = /";
      location["href"] = location["pathname"] + location["search"];
    }, _0x528bb0);
  } else {
    alert("\u8BF7\u6C42\u9A8C\u8BC1\u5931\u8D25");

将上面代码改为:

return _0x1c7f44["tn"] + "=" + _0x3227c3[0] + ";Max-age=" + _0x1c7f44["vt"] + "; path = /";

另外代码中go方法内部这个方法读取了浏览器参数,应该是判断是否为爬虫用的,经过测试可以删除,不影响cookie生成;

function _0xa5b8cd() {
    var _0x5ddf29 = window["navigator"]["userAgent"],
        _0x15ad8f = ["Phantom"];

    for (var _0x152237 = 0; _0x152237 < _0x15ad8f["length"]; _0x152237++) {
      if (_0x5ddf29["indexOf"](_0x15ad8f[_0x152237]) != -1) {
        return true;
      }
    }

    if (window["callPhantom"] || window["_phantom"] || window["Headless"] || window["navigator"]["webdriver"] || window["navigator"]["__driver_evaluate"] || window["navigator"]["__webdriver_evaluate"]) {
      return true;
    }
  }

  if (_0xa5b8cd()) {
    return;
  }

js代码修改完成后保存到本地,js测试后发现有时会报错,多次刷新观察响应的js代码发现,该网站有三套cookie生成方式,而传入参数中的ha的值有三种,分别为md5、sha1、sha256,应该是加密方式,ha的值不同,js代码不同。那么思路有了,按上面的方法分别保存三套js代码,通过提取参数中的ha值判断使用哪一套代码,执行即可正确得到cookie;

# 提取js代码中的参数并转字典
parameter = json.loads(re.findall(r'};go\((.*?)\)</script>', response.text)[0])
js_file = ''
# 判断需要使用的js代码
if parameter['ha'] == 'sha1':
    js_file = 'sha1.js'
elif parameter['ha'] == 'sha256':
    js_file = 'sha256.js'
elif parameter['ha'] == 'md5':
    js_file = 'md5.js'

最后将前面已经得到的__jsluid_s参数和最后生成的cookie一起携带去进行第三次请求,即可得到正确响应内容。

代码:

import re
import execjs
import requests
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 关闭ssl验证提示
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                  '(KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
}
url = 'https://www.yidaiyilu.gov.cn/xwzx/gnxw/87373.htm'


def get_page():
    response = requests.get(url, headers=headers, verify=False)
    return response


def get_parameter(response):
    # 获取cookie参数jsluid
    jsluid = response.headers.get('set-cookie').split(';')[0]
    # 提取js代码
    js_clearance = re.findall('cookie=(.*?);location.href=', response.text)[0]
    # 执行后获得cookie参数js_clearance
    result = execjs.eval(js_clearance).split(';')[0]
    global headers
    headers.update({'cookie': jsluid + '; ' + result})
    response = get_page()
    # 提取参数并转字典
    parameter = json.loads(re.findall(r'};go\((.*?)\)</script>', response.text)[0])
    js_file = ''
    # 判断cookie生成方式
    if parameter['ha'] == 'sha1':
        js_file = 'sha1.js'
    elif parameter['ha'] == 'sha256':
        js_file = 'sha256.js'
    elif parameter['ha'] == 'md5':
        js_file = 'md5.js'
    return parameter, js_file, jsluid


def get_cookie(param, file):
    parameter = {
        "bts": param['bts'],
        "chars": param['chars'],
        "ct": param['ct'],
        "ha": param['ha'],
        "tn": param['tn'],
        "vt": param['vt'],
        "wt": param['wt']
    }
    with open(file, 'r') as f:
        js = f.read()
    cmp = execjs.compile(js)
    # 执行js代码传入参数
    clearance = cmp.call('go', parameter)
    return clearance


def run():
    response = get_page()
    parameter, js_file, jsluid = get_parameter(response)
    clearance = get_cookie(parameter, js_file)
    global headers
    headers.update({'cookie': jsluid + '; ' + clearance})
    html = requests.get(url, headers=headers, verify=False)
    print(html.content.decode())


run()

总结:这个__jsl_clearance_s生成方式比较简单,懂一点js即可搞定。

本文地址:https://blog.csdn.net/YungGuo/article/details/109818327

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

  • supervisor下的Dockerfile的多服务镜像封装操作

    supervisor下的Dockerfile的多服务镜像封装操作

    编写dockerfile文件配置yum源cd /tmp/dockervim dockerfilefrom rhel7expose 80 22 # 向外暴露80... [阅读全文]
  • python中绕过反爬虫的方法总结

    我们在登山的途中,有不同的路线可以到达终点。因为选择的路线不同,上山的难度也有区别。就像最近几天教大家获取数据的时候,断断续续的讲过header、地址ip等一些... [阅读全文]
  • python 如何停止一个死循环的线程

    python 如何停止一个死循环的线程

    进程想要执行任务就需要依赖线程。换句话说,就是进程中的最小执行单位就是线程,并且一个进程中至少有一个线程。那什么是多线程?提到多线程这里要说两个概念,就是串行和... [阅读全文]
  • 利用python+ffmpeg合并B站视频及格式转换的实例代码

    利用python+ffmpeg合并b站视频及格式转换 b站客户端下载的视频一般有两种格式:早期的多为blv格式(由flv格式转换而来,音视频轨道在同一文件下)。... [阅读全文]
  • python3爬虫中多线程的优势总结

    有些小伙伴跟小编讨论了python中使用多线程原理的问题,就聊到了关于python多线程的弊端问题,这点可能在使用的过程中大家会能感觉到。而且之前讲过的gil也... [阅读全文]
  • python3爬虫中引用Queue的实例讲解

    我们去一个受欢迎的地方买东西,难免会需要排队等待。如果有多个窗口的话,就会有不同队列的产生,当然每个队伍的人数也会出现参差不齐的现象。我们今天所要说的queue... [阅读全文]
  • Django URL参数Template反向解析

    一、 url参数在view中传递1、带参数名:通过named group方式传递指定参数,语法为: (?p<name>pattern), n... [阅读全文]
  • python3爬虫GIL修改多线程实例讲解

    python3爬虫GIL修改多线程实例讲解

    我们打开程序后,会发现电脑的内存和cpu发生了变化。在对于前者上面,自然是希望内容占用小,cpu的利用越高越好。那有没有什么方法可以让我们的cpu达到满状态的运... [阅读全文]
  • PyCharm Community安装与配置的详细教程

    PyCharm Community安装与配置的详细教程

    【内容】: 最近python挺火,空闲时间看了几个python视频,觉得简单易懂,开发效率高,应用范围广,值得学习。如下便开始搭建学习环境,即安装一款好用的... [阅读全文]
  • python爬虫快速响应服务器的做法

    不论是打开网页或者爬取一些资料的时候,我们想要的是计算机能在最短的时间内运行出结果,不然等待的时间过长会影响下一步工作的计划。这时候我们可以给计算机一个指令,限... [阅读全文]
验证码:
Copyright © 2017-2020  萬仟网 保留所有权利. 粤ICP备17035492号-1