零、写在前面


本文涉及的反爬技术,仅供个人技术学习,禁止并做到:

  • 干扰被访问网站的正常运行
  • 抓取受到法律保护的特定类型的数据或信息
  • 搜集到的数据禁止传播、交给第三方使用、或者牟利
  • 如有可能,在爬到数据后24小时候内删除

具体可参考 2019年5月28号 颁布的 《数据安全管理办法(征求意见稿)》

一、背景


今天在爬另一家网站数据时,想直接从 ajax 接口入手,但是发现这些 request 加了额外参数来防止爬取,即在 request header 里,有一对随机key-value 参数:形如 e931588bc0dfbc5e6323 : c43dfe7cdc49b6318f43907ad4e7d9b69a23719d2e3b7b59799124408aa11cf383f459a4a558af8c64b289b7d974982aad58db705ac6784460733bd21784bde0,故意让你猜不到。

但是操作了一会,我总结了如下规律:

1、每个不同的接口 url,对应不同的 key ,但这个 key 刷新页面是不会变得。(看来 key 跟 url 有关)

2、每个 key 对应的 value 一直在变。(事后才知道 value 是根据 url 和 post body 共同决定的)

二、破解


于是通过网站被混淆过的 js ,耐心的打断点分析。

过程略。

三、结果


最后发现:

key 和 value 都是通过 HMAC(Keyed-Hashing for Message Authentication) 算法得来的。

1、HMAC 算法

HMAC 其实就等于我们平常用的 MD5 / SHA-1 去加 salt 的操作。而采用 HMAC 的好处就是,替代我们自己的 salt 算法,使得程序算法更标准化,也更安全

HMAC 可选择搭配 MD5 / SHA-1 或等等。这里用的是 SHA512

>>> import hmac
>>> key = b'secret'
>>> message = b'Hello, world!'
>>> h = hmac.new(key, message, digestmod='MD5')
>>> h.hexdigest()
'fa4ee7d173f2d97ee79022d1a7355bcf'

注意:传入的 key 和 message 都是bytes类型,所以str类型需要首先被编码为bytes

2、最终代码

注意:敏感信息被隐藏处理。

import hashlib
import hmac
import requests
import json host = 'http://example.com'
# request's param - 变化值
uri = '/api/search/example'
data = {
"cityName": "上海",
"cityCode": "31",
# 等等
} # hmac's secret - 固定值
secret = b'abcdefg' # calculate key
sign_key = hmac.new(secret, uri.lower().encode(), hashlib.sha512).hexdigest()
header_key = sign_key[10:30] # calculate value
sign_value = (uri.lower()+uri.lower() +
json.dumps(data, separators=(',', ':'), ensure_ascii=False)).lower()
header_value = hmac.new(secret, sign_value.encode(),
hashlib.sha512).hexdigest()
# print result
print(header_key, header_value)

然后我们把算出来的 key 和 value 塞入到每一次请求的 header 里,即可成功调用。

3、坑

上面代码在算 value 的时候,用了 json.dumps(),把中文 上海 转为了 "\u4e0a\u6d77",而不是上海,导致接口一直报错。

解决办法:json.dumps 多传一个参数 ensure_ascii=False

最新文章

  1. SQLServer数据库备份
  2. JsonHelper
  3. 机器学习中的数学-线性判别分析(LDA), 主成分分析(PCA)
  4. sqlserver 类似oracle的rownum功能: row_number
  5. oracle的全文索引
  6. Putty终端 模拟 远程登录 虚拟机Linux
  7. Python 基础【第三篇】输入和输出
  8. 第四篇:Eclipse Android app 工程迁移到 Android Studio
  9. office如何去除多页签
  10. [Swift]LeetCode724. 寻找数组的中心索引 | Find Pivot Index
  11. [Oracle]使用InstantClient访问Oracle数据库
  12. Java框架之Struts2(五)
  13. 【转载】JAVA消息服务JMS规范及原理详解
  14. Win10通知区域图标设置;windows10系统图标合并;Windows10系统通知合并
  15. e610. Setting Focus Traversal Keys in a Component
  16. Java如何查看死锁?
  17. 解决Visual Studio Community 2017工具栏中没有Report Viewer的问题
  18. Flex 加载dwg
  19. 局域网安全-MAC Flood/Spoof
  20. Clairewd’s message--hdu4300(Next数组的运用)

热门文章

  1. 你真的了解foreach吗?
  2. 第五章 Unity中的基础光照(1)
  3. 如何把图片变得炫酷多彩,Python教你这样实现!
  4. JQuery基础之获取和设置标签内容
  5. Kafka 安装配置 及 简单实验记录
  6. Hive Hadoop 解析 orc 文件
  7. luogu P1191 矩形 |dp
  8. cf448D Multiplication Table 二分
  9. Mysql基础02-约束
  10. 2019企业linux运维最需要的了解的一些硬件基础知识