此文章只进行技术分享,不会对任何网站进行实际上的爬取
此技术是通过WebSocket实现的,因此可以参考下面的文档对WebSocket进行学习。参考:https://www.cnblogs.com/chyingp/p/websocket-deep-in.html
1. JSPRC简介
RPC 技术是非常复杂的,对于我们搞爬虫、逆向的来说,不需要完全了解,只需要知道这项技术如何在逆向中应用就行了。
RPC 在逆向中,简单来说就是将本地和浏览器,看做是服务端和客户端,二者之间通过 WebSocket 协议进行 RPC 通信,在浏览器中将加密函数暴露出来,在本地直接调用浏览器中对应的加密函数,从而得到加密结果,不必去在意函数具体的执行逻辑,也省去了扣代码、补环境等操作,可以省去大量的逆向调试时间。
2. Sekiro-RPC
官网:https://sekiro.iinti.cn/sekiro-doc/
2.1 说明
在本地开启服务端
客户端地址:file.virjar.com/sekiro_web_client.js?_=123
参数说明
// 生成唯一标记uuid编号
function guid() {
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
// 连接服务端
var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=ws-group&clientId="+guid());
// 业务接口
client.registerAction("登陆",function(request, resolve, reject){
resolve(""+new Date());
})
- group:业务类型(接口组),每个业务一个
group,group 下面可以注册多个终端(SekiroClient),同时group 可以挂载多个 Action; - clientId:指代设备,多个设备使用多个机器提供
API 服务,提供群控能力和负载均衡能力; - SekiroClient:服务提供者客户端,主要场景为手机/浏览器等。最终的
Sekiro 调用会转发到 SekiroClient。每个client 需要有一个惟一的 clientId; - registerAction:接口,同一个
group 下面可以有多个接口,分别做不同的功能; - resolve:将内容传回给服务端的方法;
- request:服务端传过来的请求,如果请求里有多个参数,可以以键值对的方式从里面提取参数然后再做处理。
Sekiro API
2.2 使用
以某条为例,当然生成加密的算法要你们自己去找,这里只提供思路和使用方法
第二步开启客户端
这里的客户端是你要爬取数据的网站。你要做的就是将一些代码注入到网页中,注入的方法有很多,这里主要使用油猴插件实现。注意此脚本中的”signature”: window.xxxxxx.xxxxx需要你自己去js中查找。
// ==UserScript==
// @name 某条
// @namespace https://www.toutiao.com/
// @version 2024-03-12
// @description try to take over the world!
// @author You
// @match https://www.toutiao.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=xiaosuigu.top
// @grant none
// @require https://sekiro.virjar.com/sekirodoc/assets/sekiro_web_client.js
// ==/UserScript==
(function () {
'use strict';
function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) |
0).toString(16).substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4()+ S4() + S4());
}
var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=tt-test&clientId=" + guid());
/* 自定义函数 */
client.registerAction("toutiao", function (request, resolve, reject) {
var url = request['url'];
if (!url) {
reject("url 不能为空")
}
resolve({
"signature": window.xxxxxx.xxxxx({url}), "cookie":
document.cookie
})
})
})();
第三步python调用
import urllib3, requests
urllib3.disable_warnings()
def get_sig(url):
data = {
"group": "tt-test",
"action": "toutiao",
"url": url
}
res = requests.post(url="http://127.0.0.1:5620/business-demo/invoke", data=data, verify=False)
resp = res.json()
if "?" in url:
url += "&_signature={}".format(resp['signature'])
else:
url += "?_signature={}".format(resp['signature'])
return url
url = get_sig(
'https://www.toutiao.com/api/pc/list/feed?channel_id=0&min_behot_time=1636703275&refresh_count=2&category=pc_profile_recommend')
print(url)
# 那么url中就已经获取到了全部的加密参数,然后就可以调用了