文章目录
- 1. 写在前面
- 2. 接口分析
- 3. 算法脚本实现
【🏠作者主页】:吴秋霖
【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作!
【🌟作者推荐】:对爬虫领域以及JS逆向分析感兴趣的朋友可以关注《爬虫JS逆向实战》《深耕爬虫领域》
未来作者会持续更新所用到、学到、看到的技术知识!包括但不限于:各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章
作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
1. 写在前面
作者在之前的文章内有提到关于a1、webid、sec_poison_id这些Cookie组成参数的的讲解及实现算法!以及关键组成参数web_session的获取方式、这个参数之前也提到了分为游客与登录用户,那么用户在访问浏览一篇笔记的时候,一定会触发了某个接口后+1(也就是小眼睛访问量)
2. 接口分析
要实现对小眼睛的+1,首先我们需要深入去研究分析一下它触发了哪个接口。作者这里在非登录的状态下去打开一篇笔记内容,看一下发包请求,如下所示:
metrics_report这个接口在经过多次的验证与测试下,发现就是让小眼睛+1的接口。也就是说我们去请求一次这个接口那么它就会+1。但是问题来了!基于什么?应该是用户的Cookie信息,也就是当中的web_session
这里我们把请求的参数拿出来分析一下,note_id是笔记的ID、另外注意看user_id有两个,一个自己的一个笔记作者的。如下所示:
json_data = {
"note_id": "666175a3000000000d00e05e",
"note_type": 1,
"report_type": 1,
"stress_test": False,
"viewer": {
"user_id": "6676e1d0000000001c0034e8",
"followed_author": 0
},
"author": {
"user_id": "65d6ea1d000000000d024df2"
},
"interaction": {
"like": 0,
"collect": 0,
"comment": 0,
"comment_read": 0
},
"note": {
"stay_seconds": 0
},
"other": {
"platform": "web"
}
}
3. 算法脚本实现
现在需要梳理一下整个+1的流程,将实现流程使用Python代码来实现。首先第一步需要先生成游客的身份信息,通过作者之前文章内的算法实现如下:
# 生成CK的必要组成参数
async def generator_cookie_info(self):
ck_info = await self.get_core_algorithm()
return {
'a1': ck_info['a1'],
'webId': ck_info['webid'],
'sec_poison_id': ck_info['sec_poison_id']
}
上面代码中调用了核心的加密算法函数,主要就是CK组成参数的算法跟签名,如下所示:
# 最新JS算法是作者6.20重新还原的
async def get_core_algorithm(self, is_ck: bool = False, params: str = '') -> Dict[str, str]:
with open("xs-xsc620.js", encoding='utf-8') as f:
ctx = execjs.compile(f.read())
if not is_ck:
return ctx.call("getwebid")
else:
xts = ctx.call('getXs', params, self.cookies['a1'])
xtscommon = ctx.call('getXsc', xts, self.cookies['a1'])
self.headers.update({
'x-s': xts['X-s'],
'x-s-common': xtscommon,
'x-t': str(xts['X-t'])
})
接下来,我们需要拿到服务端给的web_session,通过请求调用login/activate这个接口获取,代码实现如下所示:
async def get_web_session(self):
login_activate = "/api/sns/web/v1/login/activate"
self.cookies = await self.generator_cookie_info()
login_activate_api = f'url={login_activate}' + \
json.dumps({}).replace(" ", "")
await self.get_core_algorithm(is_ck=True, params=login_activate_api)
data = json.dumps({}, separators=(',', ':')).replace(" ", "")
async with self.session.post(
f'https://edith.xhs.com{login_activate}',
cookies=self.cookies,
headers=self.headers,
data=data
) as response:
response_data = await response.json()
logger.info(f'获取web_session信息: {response_data}')
self.cookies['web_session'] = response_data['data']['session']
await self.metrics_report()
拿到web_session之后,使用完整的CK信息去请求之前我们提到的小眼睛的metrics_report接口,以此实现+1的效果,运行效果如下所示:
注意上图!流程就是先通过JS算法签名,去activate的接口拿到服务端返回的session信息,然后拼接JS算法生成的其他Cookie参数字段,访问metrics_report接口
运行脚本之前作者也是截图做了一下保存,以此为标识来记录一下程序的效果,如下所示:
程序分别使用了不同CK信息对作者自己的笔记进行了测试,测试效果如下所示(+10):