jsdom
中文文档: https://segmentfault.com/a/1190000014844043
英文文档:https://www.w3school.com.cn/js/js_htmldom_elements.asp
jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOM和 HTML 标准,用于在 nodejs 中使用
执行脚本
jsdom最强大的功能是它可以在jsdom中执行脚本。这些脚本可以修改页面的内容并访问jsdom实现的所有Web平台API。
但是,这在处理不可信内容时也非常危险。 jsdom沙箱并不是万无一失的,在DOM的<script>
内部运行的代码如果足够深入,就可以访问Node.js环境,从而访问您的计算机。 因此,默认情况下,执行嵌入在HTML中的脚本的功能是禁用的
要在页面内启用脚本,可以使用runScripts:"dangerously"
选项
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const fs = require('fs') // 读取文件
fs.readFile('crawl/yrx/js_test.html', 'utf8', function(err, data){
const dom = new JSDOM(data, {
url: 'http://match.yuanrenxue.com/match/2',
referrer: 'http://match.yuanrenxue.com/match/2',
contentType: "text/html",
userAgent: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
includeNodeLocations: true,
runScripts:"dangerously" // 运行js脚本
});
console.log(dom.window.document.cookie);
dom.window.close()
})
补 window 和 document 环境
const jsdom = require("jsdom");
const {JSDOM } = jsdom; //在jsdom中导出JSDOM对象
const {document} = (new JSDOM('<!doctype html><html><body></body></html>')).window; //导出JSDOM中window对象的doucument对象
global.document = document; //将doucument对象设置为nodejs中全局对象
global.window = document.defaultView; //将document对象中的的defaultView属性(doucument.defaultView也就是浏览器中的window对象)
// 或者
const jsdom = require("jsdom"); // v14.18.0 jsdom@19.0.0
const {JSDOM } = jsdom; //在jsdom中导出JSDOM对象
const { window } = new JSDOM('<!doctype html><html><body></body></html>'); //导出JSDOM中的window对象
global.window = window; //将window对象设置为nodejs中全局对象;
jsdom 全局安装
npm i jsdom -g
查看 jsdom 位置
npm root -g
python 中的 execjs 库也可以切换成 jsdom 来执行含有 document,window等对象的js代码
示例代码
signature = execjs.compile(js, cwd=jsdom_path).call('sign')
canvas 安装
npm install canvas --canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas/ --unsafe-perm --verbose
释义:--unsafe-perm:以root用户进行操作,--verbose:显示进度信息
Linux 安装过程中报错处理
报错信息1 /lib64/libstdc++.so.6 version CXXABI_1.3.9 not found
https://files.cnblogs.com/files/kai-/libstdcso.6.0.zip?t=1659505049 下载
cp libstdc++.so_.6.0.22 /usr/lib64/
cd /usr/lib64
rm libstdc++.so.6
ln -s libstdc++.so.6.0.22 libstdc++.so.6
strings /usr/lib64/libstdc++.so.6 | grep CXXABI_1.3.9
报错信息2 /lib64/libc.so.6: version
GLIBC_2.18' not found (required by /lib64/libstdc++.so.6)`
curl -O http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
tar zxf glibc-2.18.tar.gz
cd glibc-2.18/
mkdir build
cd build/
../configure --prefix=/usr
make -j2
make install
报错信息3 'gbk' codec can't encode character '\xe5' in position 13665: illegal multibyte sequence
Windows 电脑下使用 Python execjs 运行指定的 JS 文件,但 JS 文件中包含中文
解决方法:
进入python的安装目录,找到lib 文件夹,找到subprocess.py,将参数 encoding=“None” 修改为 encoding=“utf-8” 即可。
python\lib\subprocess.py
def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding='utf-8', errors=None):
"""Create new Popen instance."""
_cleanup()