fastrpc的使用
首先为了防止项目更新我把它fork到我的git下面的了,项目地址
git@github.com:cxapython/fastrpc.git。
这是一个python和js的项目,首先使用python3,安装所需要的依赖问题
然后直接,启动sekiro服务
python3 main.py
之际将client.js文件放到油猴脚本。
例如下面的xhs的。x-s获取
// ==UserScript==
// @name getXS
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.xiaohongshu.com/search_result*
// @icon https://www.google.com/s2/favicons?sz=64&domain=xiaohongshu.com
// @grant none
// ==/UserScript==
function WSClient(wsURL) {
this.wsURL = wsURL;
this.handlers = {};
this.socket = {};
// check
if (!wsURL) {
throw new Error('wsURL can not be empty!!')
}
this.webSocketFactory = this.resolveWebSocketFactory();
this.connect()
}
WSClient.prototype.resolveWebSocketFactory = function () {
if (typeof window === 'object') {
var theWebSocket = window.WebSocket ? window.WebSocket : window.MozWebSocket;
return function (wsURL) {
function WindowWebSocketWrapper(wsURL) {
this.mSocket = new theWebSocket(wsURL);
}
WindowWebSocketWrapper.prototype.close = function () {
this.mSocket.close();
};
WindowWebSocketWrapper.prototype.onmessage = function (onMessageFunction) {
this.mSocket.onmessage = onMessageFunction;
};
WindowWebSocketWrapper.prototype.onopen = function (onOpenFunction) {
this.mSocket.onopen = onOpenFunction;
};
WindowWebSocketWrapper.prototype.onclose = function (onCloseFunction) {
this.mSocket.onclose = onCloseFunction;
};
WindowWebSocketWrapper.prototype.send = function (message) {
this.mSocket.send(message);
};
return new WindowWebSocketWrapper(wsURL);
}
}
if (typeof weex === 'object') {
// this is weex env : https://weex.apache.org/zh/docs/modules/websockets.html
try {
console.log("test webSocket for weex");
var ws = weex.requireModule('webSocket');
console.log("find webSocket for weex:" + ws);
return function (wsURL) {
try {
ws.close();
} catch (e) {
}
ws.WebSocket(wsURL, '');
return ws;
}
} catch (e) {
console.log(e);
//ignore
}
}
//TODO support ReactNative
if (typeof WebSocket === 'object') {
return function (wsURL) {
return new theWebSocket(wsURL);
}
}
// weex 鍜� PC鐜鐨剋ebsocket API涓嶅畬鍏ㄤ竴鑷达紝鎵€浠ュ仛浜嗘娊璞″吋瀹�
throw new Error("the js environment do not support websocket");
};
WSClient.prototype.connect = function () {
console.log('sekiro: begin of connect to wsURL: ' + this.wsURL);
var _this = this;
// 涓峜heck close锛岃
// if (this.socket && this.socket.readyState === 1) {
// this.socket.close();
// }
try {
this.socket = this.webSocketFactory(this.wsURL);
} catch (e) {
console.log("sekiro: create connection failed,reconnect after 2s");
setTimeout(function () {
_this.connect()
}, 2000)
}
this.socket.onmessage(function (event) {
_this.handleSekiroRequest(event.data)
});
this.socket.onopen(function (event) {
console.log('sekiro: open a sekiro client connection')
});
this.socket.onclose(function (event) {
console.log('sekiro: disconnected ,reconnection after 2s');
setTimeout(function () {
_this.connect()
}, 2000)
});
};
WSClient.prototype.handleSekiroRequest = function (requestJson) {
console.log("receive sekiro request: " + requestJson);
var request = JSON.parse(requestJson);
var seq = request['__sekiro_seq__'];
console.log('request', request)
if (!request['action']) {
// this.sendFailed(seq, 'need request param {action}');
return
}
var action = request['action'];
if (!this.handlers[action]) {
// this.sendFailed(seq, 'no action handler: ' + action + ' defined');
return
}
const theHandler = this.handlers[action];
var _this = this;
try {
theHandler(request, function (response) {
try {
_this.sendSuccess(seq, response)
} catch (e) {
_this.sendFailed(seq, "e:" + e);
}
}, function (errorMessage) {
_this.sendFailed(seq, errorMessage)
})
} catch (e) {
console.log("error: " + e);
_this.sendFailed(seq, ":" + e);
}
};
WSClient.prototype.sendSuccess = function (seq, response) {
var responseJson;
if (typeof response == 'string') {
try {
responseJson = JSON.parse(response);
} catch (e) {
responseJson = {};
responseJson['data'] = response;
}
} else if (typeof response == 'object') {
responseJson = response;
} else {
responseJson = {};
responseJson['data'] = response;
}
if (Array.isArray(responseJson)) {
responseJson = {
data: responseJson,
code: 0
}
}
if (responseJson['code']) {
responseJson['code'] = 0;
} else if (responseJson['status']) {
responseJson['status'] = 0;
} else {
responseJson['status'] = 0;
}
responseJson['__sekiro_seq__'] = seq;
var responseText = JSON.stringify(responseJson);
console.log("response :" + responseText);
this.socket.send(responseText);
};
WSClient.prototype.sendFailed = function (seq, errorMessage) {
if (typeof errorMessage != 'string') {
errorMessage = JSON.stringify(errorMessage);
}
var responseJson = {};
responseJson['message'] = errorMessage;
responseJson['status'] = -1;
responseJson['__sekiro_seq__'] = seq;
var responseText = JSON.stringify(responseJson);
console.log("sekiro: response :" + responseText);
this.socket.send(responseText)
};
WSClient.prototype.registerAction = function (action, handler) {
if (typeof action !== 'string') {
throw new Error("an action must be string");
}
if (typeof handler !== 'function') {
throw new Error("a handler must be function");
}
console.log("sekiro: register action: " + action);
this.handlers[action] = handler;
return this;
};
function guid() {
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
const client = new WSClient("ws://localhost:8000/ws/" + guid());
client.registerAction("clientTime",function(request, resolve,reject ){
resolve(""+new Date());
})
client.registerAction("html",function(request, resolve,reject ){
resolve(document.documentElement.outerHTML);
})
client.registerAction("cookies",function(request, resolve,reject ){
resolve(document.cookie);
})
client.registerAction("get_headers",function(request, resolve,reject ){
console.log("request",request)
var params = request.param
var url_path = params.url_path
var param = params.param
var result = window._webmsxyw(url_path,params)
resolve(result);
})
然后在python中这样使用
这里以post请求为例,参数action和param是固定的名称。
action就是请求下面方法的内容,这里是get_headers。
post_data = {"action": "get_headers", "param": {"url_path": url_path, "param": json_data}}
response = None
for i in range(10):
try:
response = requests.post("http://localhost:8000/invoke", headers=headers2,
data=json.dumps(post_data, ensure_ascii=False, separators=(',', ':')).encode(),
timeout=3)
break
except Exception:
pass
请求的方法就是上面的js的这段代码
client.registerAction("get_headers",function(request, resolve,reject ){
console.log("request",request)
//这里面写逻辑就好了
var params = request.param
var url_path = params.url_path
var param = params.param
var result = window._webmsxyw(url_path,params)
resolve(result); //返回内容
})