本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
ps:本文以某语在线索引页为例讲解一下AES反反爬案例,AES加密过程还是极为复杂的可自行百度了解,为什么说大道至简呢,话不多少我们直接进入主题,网站地址
- 老规矩,先清cookies再抓包
可见接口参数明了无加密项返回数据为json结构清晰,直接curl模拟请求试一下-curl转requests
没问题正常返回数据(结束了?)换个关键字试一下
果然不是这么简单,提示ip进入黑名单明显不真实(障眼法),可见没有cookies那问题只能出现在headers中
可见headers中只有两个参数(vtoken,htoken)看似为认证参数经过多次检索发现vtoken值不变,而htoken值根据索引关键字的变化而改变(就是他了),到这里已经明了了此接口请求只需要拿到htoken没有其他问题了!
- 先检索源码看看效果,运气不错源码未作任何混淆ok Debug看一下方法是什么
一目了然这不就是AES加密吗,debug可知参数为索引关键字,r.a正是CryptoJS。所谓的大道至简就是这时候我们不需要管什么对称不对称公钥私钥乱七八糟的,直接整个函数拷走r.a替换为CryptoJS,使用python的execjs方法执行一下看一下结果
没错正是curl,headers中的htoken值,最后我们完善一下代码
# -*- coding: utf-8 -*-
import csv
import sys
import time
import execjs
import requests
'''
@Description:
@Time : 2022/11/9 15:18
@Author :@zhangmengzhuo
@File : shuyu.py
@version :python 3.6
@Software: PyCharm
'''
def get_htoken(cihui):
htmlstr = '''
function cc(t) {
const CryptoJS = require('crypto-js');
var e = CryptoJS.enc.Utf8.parse("46cc793c53dc451b")
, n = CryptoJS.enc.Utf8.parse(t.trim())
, o = CryptoJS.AES.encrypt(n, e, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return o.toString()
};
'''
ctx = execjs.compile(htmlstr)
result = ctx.call('cc', cihui)
print(result)
return result
def get_data(cihui):
htoken = get_htoken(cihui)
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/json;',
'Origin': 'https://www.termonline.cn',
'Pragma': 'no-cache',
'Referer': 'https://www.termonline.cn/search?k=%E4%BF%83%E5%87%9D%E8%A1%80%E7%96%97%E6%B3%95',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36',
'htoken': f'{htoken}',
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
json_data = {
'k': f'{cihui}',
'highlight': True,
'pno': 1,
'match': '3',
'dbids': [
'1',
],
'sdms': [],
'gbnds': [],
'warn': 0,
'uuid': f'{int(time.time())}',
}
response = requests.post('https://www.termonline.cn/tm/api/tm/search', headers=headers, json=json_data).json()
print(response.text)
if __name__ == '__main__':
cihui_list = ['促凝血疗法','便白细胞阳性','促肾上腺皮质素刺激试验','先兆子痫']
for cihui in cihui_list:
get_data(cihui)
- 总结
这个案例相对比较简单,抓包,模拟接口测试动态参数,debug追踪参数生成位置,生成参数,如有问题欢迎大家留言指出。此教程只做交流学习使用,合理爬虫,后果自负