【爬虫与反爬】记一次网址编码研究
相爱相杀的爬虫与反爬工程师啊……愿你们和谐相处。
前些日子写爬虫时遇到一个比较奇怪的编码,是构造目标网址的一个组成部分,我更倾向于说是编码而不是加密,虽然的确有点加密的意思。当时算是一个绕不开的需求,所以费了很大功夫研究了出来。有些时候网站的前端、后端工程师会用尽办法反爬,而写爬虫的人又要想尽办法反反爬,真可谓是相爱相杀了。尤其是在编码(加密)这件事上,我随口胡诌一个编码过程,就很难逆向推导出来,这次有点运气成分,也有点规律可寻,所以记录下来给大家。
为了让大家专注于编码本身,我就不把真实网址放出来了。大家只需要知道网址构成大概是这个样子
https://www.wtf.com/N3V5bw==.html
这是最终的一个目标页,后面的N3V5bw==在这里的含义是36672。由于数据量比较大,从列表页没办法抓取到所有的href,所以需要自己构造网址,而网址又不可能是没有规律的,想办法观察到了36672(可以理解成一个资源的ID)和N3V5bw==的对应关系。
N3V5bw==这样的形式,很容易判断出是base64编码,于是base64解码,得到7uyo,没有什么明显思路,显然还做了其他操作(后来知道是自己经验不足,离答案挺近的)。
然后手动获取到了一些一一对应关系。
id |
base64 |
base64解码 |
---|---|---|
1 |
YQ |
a |
2 |
aw |
k |
3 |
dQ |
u |
4 |
MTQ= |
14 |
5 |
MWU= |
1e |
6 |
MW8= |
1o |
7 |
MXk= |
1y |
8 |
Mjg= |
28 |
9 |
Mmk= |
2i |
10 |
MnM= |
2s |
11 |
MzI= |
32 |
12 |
M2M= |
3c |
13 |
M20= |
3m |
到这一步还是没什么思路,只能又想办法多获取了一些对应关系(前面提到了没有统一的入口,这一步也费了一些周折)
id |
base64 |
base64解码 |
---|---|---|
1 |
YQ== |
a |
2 |
aw== |
k |
3 |
dQ== |
u |
4 |
MTQ= |
14 |
5 |
MWU= |
1e |
6 |
MW8= |
1o |
7 |
MXk= |
1y |
8 |
Mjg= |
28 |
9 |
Mmk= |
2i |
10 |
MnM= |
2s |
11 |
MzI= |
32 |
12 |
M2M= |
3c |
13 |
M20= |
3m |
14 |
M3c= |
3w |
15 |
NDY= |
46 |
16 |
NGc= |
4g |
17 |
NHE= |
4q |
18 |
NTA= |
50 |
19 |
NWE= |
5a |
20 |
NWs= |
5k |
21 |
NXU= |
5u |
22 |
NjQ= |
64 |
23 |
NmU= |
6e |
24 |
Nm8= |
6o |
25 |
Nnk= |
6y |
26 |
Nzg= |
78 |
27 |
N2k= |
7i |
28 |
N3M= |
7s |
29 |
ODI= |
82 |
30 |
OGM= |
8c |
现在的主要考虑是如何从第一列到第三列。
刚开始我观察第三列的时候看到最后一位是18循环的,第一位有点类似4循环,还以为有什么mod18的套路在里面,后面看到组成是0~9和a~z(一共36),突然猜测会不会是36进制…
于是把ID转36进制。
ID |
ID转36进制 |
解码结果 |
解码结果36进制转10进制 |
---|---|---|---|
1 |
1 |
a |
10 |
2 |
2 |
k |
20 |
3 |
3 |
u |
30 |
4 |
4 |
14 |
40 |
5 |
5 |
1e |
50 |
6 |
6 |
1o |
60 |
7 |
7 |
1y |
70 |
8 |
8 |
28 |
80 |
9 |
9 |
2i |
90 |
10 |
a |
2s |
100 |
11 |
b |
32 |
110 |
12 |
c |
3c |
120 |
13 |
d |
3m |
130 |
14 |
e |
3w |
140 |
15 |
f |
46 |
150 |
16 |
g |
4g |
160 |
17 |
h |
4q |
170 |
18 |
i |
50 |
180 |
19 |
j |
5a |
190 |
20 |
k |
5k |
200 |
21 |
l |
5u |
210 |
22 |
m |
64 |
220 |
23 |
n |
6e |
230 |
24 |
o |
6o |
240 |
25 |
p |
6y |
250 |
26 |
q |
78 |
260 |
27 |
r |
7i |
270 |
28 |
s |
7s |
280 |
29 |
t |
82 |
290 |
30 |
u |
8c |
300 |
于是结果就比较明显了。
所用到的规则为:ID*10转36进制后进行base64编码。
事后反思了一下,主要是极少见到36进制,所以从一开始就没往那边动心思,直到看到了很多数据以后觉得18循环,跟常见的4,8,16没关系,才猜测到36进制上面。
这也算是一点小记录和小经验。 还真是设计规则的人随便胡诌一个规则,破解规则的人就要费很大力气了…… 最后的代码是这么写的:
import base64
def baseN(num, b):
return ((num == 0) and "0") or (baseN(num // b, b).lstrip("0") + "0123456789abcdefghijklmnopqrstuvwxyz"[num % b])
def wtf(num):
return base64.b64encode(baseN(num * 10, 36).encode()).decode()
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Rust日报】2020-09-06 Evil_DLL 用来测试注入方法的DLL
- 【Rust日报】2020-09-05 微软在c++静态分析工具实现了一些rust的安全规则
- 一起来玩玩WebGL
- 自研网关:多项目的swagger聚合功能
- Prometheus 如何做到“活学活用”,大牛总结的避坑指南
- 文档驱动 —— 表单组件(一):表单元素组件 优点缺点选择文本类的Inputcheck 多选value的类型问题
- Vue3.0源码结构分析
- 【每周一库】- cached - 缓存结构型、辅助函数记忆化
- meta生成器 —— 表单元素组件 meta表单代码meta的模板data变幻
- 不用写代码也能做表单 —— 加载meta即可 菜单表单加载json运行效果。ModelAbout
- 从0到1,手把手教你入门 etcd
- 数据结构:手把手带你了解 ”图“ 所有知识!(含DFS、BFS)
- 设计模式之单例模式
- AndroidStudio创建JNI 工程与调用
- Java 版植物大战僵尸思路和源码分享!