在使用 Python 爬虫的时候需要使用到类似于前端的 CryptoJS 库来生成密文或者解密密文,以达到反反爬虫的目的。但是在 Python 中并不好实现 JavaScript 的 CryptoJS 库。
所以可以使用 js2py 来直接运行 JavaScript 代码调用 CryptoJS 库。
使用示例
# pip install js2py
import js2py
CryptoJS = js2py.require('crypto-js')
plain_string = "Hello😀!这是一段明文。"
encrypted_string = CryptoJS.AES.encrypt(plain_string, "test").toString()
decrypted_string = CryptoJS.AES.decrypt(encrypted_string, "test").toString(CryptoJS.enc.Utf8)
如果没有安装 NodeJS 环境,直接导入脚本也是可行的:
# 替换掉 CryptoJS = js2py.require('crypto-js')
context = js2py.EvalJs()
with open('./crypto-js.min.js', 'r') as f:
context.eval(f.read())
CryptoJS = context.eval('CryptoJS')
修复编解码漏洞
由于 js2py 代码中错误将 escape 和 unescape 函数的实现等同于 URI 编解码,所以导致了非 ASCII 编解码不正确的问题,提供修复方法:
import re
import js2py
from js2py.host import jsfunctions
@js2py.base.Js
def escape(text):
def replacer(match):
char = match.group()
code = ord(char)
if code <= 0xff:
return f'%{code:02X}'
else:
return f'%u{code:04X}'
return re.sub(r'[^A-Za-z0-9@*_+\-./]', replacer, text.to_python())
@js2py.base.Js
def unescape(text):
def replacer(match):
u_group = match.group(1)
hex_group = match.group(2)
if u_group is not None:
return chr(int(u_group, 16))
elif hex_group is not None:
return chr(int(hex_group, 16))
return match.group()
return re.sub(r'%u([0-9A-Fa-f]{4})|%([0-9A-Fa-f]{2})', replacer, text.to_python(), flags=re.IGNORECASE)
jsfunctions.escape = escape
jsfunctions.unescape = unescape
# 这里可以继续执行加密相关代码
已提交 PR 等待开发者合并。










