获取某头条签名_signature参数
在写一个头条聚合网站 https://tttt.today ,想爬取今日头条的热点新闻,发现有前端加密的参数
下图是头条热点新闻
下图是头条热点新闻的http请求,可以看到其中只带了一个_signature参数。
如何获取该参数,下面讲解思路和相关操作步骤。
1.全局搜 _signature 找到出现位置
可以看到_signature=n,而n是一个u函数获取的,需要进入u函数查看,在var n=u(p.getUri(e),e);处打断点。
2.在u函数处打断点,并在页面再次触发热点新闻的请求(点击 换一换)
然后鼠标悬停到u函数,可以找到u函数的源文件,点击进入
3.找到函数u,并在返回结果处 打断点
找到u函数,并在return处打断点,
4.这里有各种三元表达式,不容易一眼看出到底干了什么。这里我们进入console去尝试输入各个表达式的各个部分
括号由外到内,一个个尝试。 chrome调试时,点击一个括号可以看到其配对的括号是哪一个,我们选择最前面的括号, 找到 括号内语句
(null === (a = null === (n = window.byted_acrawler) || void 0 === n ? void 0 : n.sign) || void 0 === a ? void 0 : a.call(n, o))
将其输入console回车 ,也可以将其他括号中的部分分别输入回车,测试:
我们可以看到,
(null === (a = null === (n = window.byted_acrawler) || void 0 === n ? void 0 : n.sign) || void 0 === a ? void 0 : a.call(n, o))
这句回车执行后 已经生成了加密字符串,说明已经执行了相关函数。
5.经对比测试,a即为n.sign,是一个函数,来自acrawler.js
找到方法的js源
方法1:文件鼠标悬停到window.byted_acrawler上,点开prototype
方法2:在console中输入a回车,点击返回的方法,也可以跳转到对应的js文件。
6.acrawler.js本地执行
通过查看acrawler.js内容,发现应为jsvmp保护的代码。只能将整个js抓到本地来执行
因为node和浏览器的环境不一样, 需要补环境 (搜 js补环境)
6.1 先将 acrawler.js 复制到一个test.js中。
var glb;
(glb = "undefined" == typeof window ? global : window)._$jsvmprt = function(b, e, f) {
function a() {
if ("undefined" == typeof Reflect || !Reflect.construct)
return !1;
if (Reflect.construct.sham)
return !1;
if ("function" == typeof Proxy)
return !0;
try {
return Date.prototype.toString.call(Reflect.construct(Date, [], (function() {}
))),
!0
} catch (b) {
return !1
}
}
///……省略……
///……省略……
///……省略……
0, "undefined" != typeof history ? history : void 0, "undefined" != typeof Image ? Image : void 0, "undefined" != typeof console ? console : void 0, "undefined" != typeof PluginArray ? PluginArray : void 0, "undefined" != typeof indexedDB ? indexedDB : void 0, "undefined" != typeof DOMException ? DOMException : void 0, "undefined" != typeof parseInt ? parseInt : void 0, "undefined" != typeof String ? String : void 0, "undefined" != typeof Array ? Array : void 0, "undefined" != typeof Error ? Error : void 0, "undefined" != typeof JSON ? JSON : void 0, "undefined" != typeof Promise ? Promise : void 0, "undefined" != typeof WebSocket ? WebSocket : void 0, "undefined" != typeof eval ? eval : void 0, "undefined" != typeof setTimeout ? setTimeout : void 0, "undefined" != typeof encodeURIComponent ? encodeURIComponent : void 0, "undefined" != typeof encodeURI ? encodeURI : void 0, "undefined" != typeof Request ? Request : void 0, "undefined" != typeof Headers ? Headers : void 0, "undefined" != typeof decodeURIComponent ? decodeURIComponent : void 0, "undefined" != typeof RegExp ? RegExp : void 0]);
function get_signature(){
return window.byted_acrawler.sign({url: 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'})
}
try{
let signature = get_signature()
console.log("signature:")
console.log(signature)
}catch(e){
console.log(e)
}
6.2 安装v_jstools插件
下载https://github.com/cilame/v_jstools 然后解压,在chrome chrome://extensions/ 中, 加载本地v_jstools插件
配置v_jstools,如下图
刷新网站,点击v_jstools中的按钮->生成临时环境
提示:已将代码存放到剪贴板中。
然后将已复制的代码,粘贴到 6.1中代码块前面, 整块代码
var v_saf;!function(){var n=Function.toString,t=[],i=[],o=[].indexOf.bind(t),e=[].push.bind(t),r=[].push.bind(i);function u(n,t){return-1==o(n)&&(e(n),r(`function ${t||n.name||""}() { [native code] }`)),n}Object.defineProperty(Function.prototype,"toString",{enumerable:!1,configurable:!0,writable:!0,value:function(){return"function"==typeof this&&i[o(this)]||n.call(this)}}),u(Function.prototype.toString,"toString"),v_saf=u}();
function _inherits(t, e) {
t.prototype = Object.create(e.prototype, {
constructor: { value: t, writable: !0, configurable: !0 }
}), e && Object.setPrototypeOf(t, e) }
Object.defineProperty(Object.prototype, Symbol.toStringTag, {
get() { return Object.getPrototypeOf(this).constructor.name }
});
var v_new_toggle = true
//……省略……
var v_to_time = +new v_Date
// var v_to_time = +new v_Date('Sat Sep 03 2022 11:11:58 GMT+0800') // 自定义起始时间
v_new_toggle = undefined;
//以上是 补环境的内容
//以下是 acrawler.js 原内容
var glb;
(glb = "undefined" == typeof window ? global : window)._$jsvmprt = function(b, e, f) {
function a() {
//……省略……
6.3 在test.js最后 再写一个调用sign函数的方法
function get_signature(){
return window.byted_acrawler.sign({url: 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'})
}
try{
let s = get_signature()
console.log("here is signature:")
console.log(s)
}catch(e){
console.log(e)
}
在命令行执行,
node test.js
我们便可以得到_signature
here is signature:
_02B4Z6wo00f01K8F4eQAAIDBBFTbeEzvBHSvJW1AAE8-dabAXl2YU--dHBGeGOWdkIq2MCKZAIffl5LvcS-54wjwUsnyJPni.Z73PiFW4i.kwj.q-O8.qYFmk2kcZD2455.0oZlc9YPR064yee
在postman中输入_signature的值,调用相关接口,可以成功获取返回,说明_signature是正确的。
7.python 中使用 execjs 调用js 获取signature参数,执行http request 获取热点新闻
import execjs
def get_signature(): # 解密signature参数
with open('test.js', encoding='utf-8')as f:
jscode = f.read()
signature = execjs.compile(jscode).call('get_signature')
return signature
s=get_signature()
print(s)