该博文仅限技术交流,请勿滥用
也是刚跑通这个JSRPC的解决方案,所以会一步一步比较详细的去介绍使用方法。
个人认为呀,需要补环境但是jsdom无法解决的时候。扣算法能力不足,对js了解不深的时候。直接扣下的js代码无法用python的第三方库运行的时候(或可运行但结果不可用)。
这时候,可能就需要用到JSRPC去解决了。
当你完全不了解JSRPC,但却需要使用它的时候。你需要怎么办?
1,首先到git下载exe文件:
它是可运行的,下载完直接点两下会弹一个cmd,就运行起来了。如下图:
2,打开知乎页面之后在打开控制台:
3,然后我们需要JSRPC项目里的JsEnv.js文件。可以进到链接,直接去copy它的这个js代码,然后粘贴到控制台,效果如下:
4,继续在控制台粘贴如下代码:
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zhihu&name=xze96");
在上面代码有 group=zhihu&name=xze96 这个。这里面的zhihu,xze96,这是可以改的,但是要确保我们等会写的python代码里,跟这俩字段保持一致就行。
输入之后回车:
这样子就代表已经连接通信了。
5,我们扣下来的代码,在末尾添加如下代码:
然后把整个扣下来改完的js粘贴进控制台:
6,这个时候,我们写一下python连接JSRPC的代码:
7:然后我们就不用再去操作浏览器或者其他了,直接写好代码在pycharm运行。运行结果:
可以看到数据都正常返回了的。改写关键词依旧是可以从这个接口拿到数据。
下面是python代码:
import hashlib
import urllib.parse
import requests
def md5hex(word):
m = hashlib.md5()
m.update(word.encode("utf-8"))
return m.hexdigest()
def getSign(md5):
# 一,启动exe程序
# 二,打开浏览器网站,在控制台注入jsEnv中的代码
# 三,继续在控制台 var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zhihu&name=xze96"); 注入通信
# 四,复制缺失环境的js代码粘贴到控制台
data = {
"group": "zhihu",
"name": "xze96",
"action": "zhihuSign",
"param": md5
}
url = "http://127.0.0.1:12080/go"
res = requests.post(url, data=data)
sign = res.json()['data']
return sign
def zhiHu(keyword):
cookie = '"AJBsNreRQBCPTnUIjLaLd2xSWLQtcZGToV8=|1571991072"'
headers = {
'accept': '*/*',
'cookie': 'd_c0={};'.format(cookie),
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
'x-api-version': '3.0.91',
'x-app-za': 'OS=Web',
'x-requested-with': 'fetch',
'x-zse-93': '101_3_3.0',
'x-zst-81': '3_2.0aR_sn77yn6O92wOB8hPZnQr0EMYxc4f18wNBUgpTQ6nxERFZKRY0-4Lm-h3_tufIwJS8gcxTgJS_AuPZNcXCTwxI78YxEM20s4PGDwN8gGcYAupMWufIeQuK7AFpS6O1vukyQ_R0rRnsyukMGvxBEqeCiRnxEL2ZZrxmDucmqhPXnXFMTAoTF6RhRuLPF7FBFcNGaqwmSwX8Iht9WgYGwv3Bf9psc0o_Y_wqx9SmjuFxceXMTDH0IbeTv4xMeXwM6gt0eLLfJGHxeMcqGXY99DrqZCe8UhxB6UxCTwO1cqwpUwVLNGtGtvOyFCHsZD38Q9o1ubgB09Sp20N1MAXOCqwONceMrRgBkJxMowe_VJSxOqfzKLFqYqU_JMoKhgH1YuYqFugMQie1CCYfdggONJuKiGwLZDS1Zw38EJNMc8VsCcfOBDofkQgO2Co8bLS9HDC0gg9MI9gXYUC8KHw0xhpfAJOYwwLCGrSC'
}
uri = '/api/v4/search_v3?gk_version=gz-gaokao&t=general&q={}&correction=1&offset=0' \
'&limit=20&filter_fields=&lc_idx=0&show_all_topics=0&search_source=Normal'.format(urllib.parse.quote(keyword))
print(uri)
s = headers['x-zse-93'] + '+' + uri + '+' + cookie + '+' + headers['x-zst-81']
smd5 = md5hex(s)
sign = getSign(smd5)
print(sign)
info = '2.0_' + sign
headers['x-zse-96'] = info
api = 'https://www.zhihu.com' + uri
resp = requests.get(api, headers=headers)
print(resp.json())
if __name__ == '__main__':
zhiHu('贵阳通报 27 死车祸情况')
整篇下来其实没有去讲怎么把某乎的js代码抠出来。因为网上资源比较多,这里多说也没有意义,但是有个难点就是js代码扣下来其实是不能用的。
exports is not defined。
因为对js了解不多,这个问题也是卡了我很久。
最后还是看了很多资料和大佬的博客才解决:
另外,JSRPC也适用某条的_signature。