猿人学反混淆刷题平台:https://match.yuanrenxue.com/match/4
# 第四题: 抓取 5 页数据,并求和
# 先抓包,看下请求,发现 headers 或者参数没有什么可疑加密,但是返回的数据都是密文🥵
# 打个 XHR 断点,尝试找一下加密位置,发现请求成功之后,对数据做了一些处理
datas = data.info; // 请求数据中的 info 赋值给 datas
$('.number').text('').append(datas); //class 为 number 的标签里添加 datas
var j_key = '.' + hex_md5(btoa(data.key + data.value).replace(/=/g, ''));
// 请求数据的 key 和 value 相加并 base64 转码,然后把 '=' 去掉再加个 '.',再进行 md5 加密,/g 是全局匹配,可以理解为多次匹配
$(j_key).css('display', 'none'); // 给 class 为 j_key 的标签添加样式,display=none 就是不显示
$('.img_number').removeClass().addClass('img_number') // 把 class 为 img_number 的类全部删除,再添加 img_number 类
# 看一下
data.info
是什么鬼东西。数据里面有
td
标签和img
标签,复制出来放到pycharm
格式化一下,可以看出就是一段html
代码,图片的src
属性用base64
编码的标签中
class
有img_number
和一段看似md5
加密的 32 位值,style
设置了左偏移量,看页面渲染的源码td
标签就是上面js
添加的
# 大致了解了一下反爬的思路,百度搜的。。。
大概就是每个数字对应一张图片,然后图片通过偏移量排序,无用的图片设置了不显示,偏移量计算还要算上图片的本来位置(这顺序的问题还是问了大佬才知道。。。
css
根基太薄弱)我又重新抓了一下包,看到每个数字对应一个密文的
url
,多次刷新发现是固定的。可以用猿人学的工具比较:http://tool.yuanrenxue.com/
# 知道了流程,下面就是
python
实现请求把数字对应
url
做成字典,方便后面取值请求页面数据,把每页显示的数字图片通过偏移量排序,每组数字有四个数字,按源码的位置再加上偏移量,每张图是 11 的 宽度
最终偏移量 = 源码位置 * 11 + 偏移量
比如下图标的顺序:
第一个位置是 3,偏移量: 0 x 11 + 11.5 = 11.5
第二个位置 7,偏移量: 1 x 11 - 11.5 = - 0.5
第三个位置 7,偏移量: 2 x 11 + 0 = 22
第四个位置 8,偏移量: 3 x 11 + 0 = 33
然后根据偏移量把数字排序就是正确的数字了
主要是理清逻辑,里面的
md5
测试了就是正常的md5
,没有魔改,代码如下:session = requests.session()
session.headers = headers
s = 0
for i in range(1, 6):
params = (
('page', str(i)),
)
response = session.get('https://match.yuanrenxue.com/api/match/4', params=params, cookies=cookie)
json_data = response.json()
info = json_data['info']
md5_value = get_md5(json_data['key'] + json_data['value'])
items = etree.HTML(info).xpath("//td")
for item in items:
imgs = item.xpath("./img")
nums = []
index = 0
for img in imgs:
src = img.xpath("./@src")[0] # 通过 src 去刚开始生成的列表里获取数字
cl = img.xpath("./@class")[0].split()[1] # 数字的 md5 class
left_v = re.search(r"-?\d+\.?\d?", img.xpath("./@style")[0]).group() # 偏移量
if cl != md5_value: # 相等的不显示
# 把显示的数字和偏移量组成元组存到列表里
nums.append((index * 11 + float(left_v), number_list[src]))
index += 1
new_nums = sorted(nums, key=lambda x: x[0]) # 把列表通过偏移量排序,然后获得数字的正确顺序
s += int(''.join([n[1] for n in new_nums])) # 遍历出数字拼成整数 然后追加和
print("和:", s)
数字对应
url
的字典,请求头和get_md5
函数没有贴在上面