网页数据抓取-JS处理
优采云 发布时间: 2022-05-06 06:08网页数据抓取-JS处理
PC端在请求数据时会生成一些加密参数,服务端会先校验这些参数,如果参数不对就不会返回正常的数据。一般这些参数会放在header里面。由于用selenium模拟浏览器操作效率很低,不推荐模拟浏览器抓取数据,先看看能否找到对应的js代码。不推荐将js代码翻译为指定语言的代码,如果js更新之后,再重新翻译,工作量太大。可以模拟js的运行环境直接执行指定的js代码。
一、找出对应的js方法 1、抓取请求头,看看里面的不常见的参数。 2、使用postman,将header加上,请求URL看返回数据是否正常。 3、将header里面的参数挨个删除,看是否可以正常返回数据,保留最精简的header,有问题便于分析。 4、使用浏览器网络功能,搜索参数名称,找到对应的js文件,“选择优质打印”(两个大括号的标志),然后在对应位置打上断点,开始一步步调试。调试过程中可以通过控制台将关键方法的值打印出来,便于验证数据。 5、将对应方法体全部复制出来。 6、通过js模拟环境或者直接在浏览器执行对应方法,验证数据是否正确。如果不正确重复第4步。
二、js模拟环境
首先需要node.js环境和jsdom插件。1、node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,这使得 Node.js 的性能非常好。。Node.js 应用程序在单个进程中运行,无需为每个请求创建新的线程。Node.js 在其标准库中提供了一组异步的 I/O 原语,以防止 JavaScript 代码阻塞,通常Node.js 中的库是使用非阻塞范式编写的,使得阻塞行为成为异常而不是常态。2、jsdom jsdom是一个纯粹由 javascript 实现的一系列 web标准,特别是 WHATWG 组织制定的DOM和 HTML 标准,用于在 nodejs 中使用。大体上来说,该项目的目标是模拟足够的Web浏览器子集,以便用于测试和挖掘真实世界的Web应用程序。
const jsdom = require("jsdom"); const { JSDOM } = jsdom; // 导出jsdom构造函数const dom = new JSDOM(`<p>Hello world`); // 生成的对象是JSDOM类的一个实例,其中包括 window 对象在内的许多有用的属性和方法。console.log(dom.window.document.querySelector("p").textContent); // "Hello world"window = dom.windowdocument = window.document</p>
*** 为什么不使用js2py,因为js2py是将js代码转换为Python代码,不支持dom操作。jsdom是可以支持的。***
三、在Python中调用js方法 PyExecJS用于实现在Python中运行JavaScript代码的功能,移植自Ruby的ExecJS库。该库自2018年以来已经停止维护(目前更好的库为js2py),但我们仍然可以用它在Python中解决一些JavaScript代码的运行问题。
四、环境配置假设已配置python环境,现在需要安装node.js环境和jsdom插件。会遇到一些因为知识存在盲区导致的坑。1、安装node.js和jsdom使用的node.js指定版本为16.13.0,下载地址 mkdir /opt/software/ && cd /opt/software/tar -xvf node-v10.9.0-linux-x64.tar.xzmv node-v10.9.0-linux-x64 nodejs建立软连接,变为全局 ①ln -s /opt/software/nodejs/bin/npm /usr/local/bin/ ②ln -s /opt/software/nodejs/bin/node /usr/local/bin/然后在程序执行目录下安装jsdom包。五、踩坑记录1、python代码执行时一直提示"atob is not defined",这个问题从上网上搜索时有很多答案,但是都无法解决。使用node命令直接执行js文件,就会有另一种提示,提示缺少canvas依赖,很奇怪为什么没有把对应的依赖都给安装上。然而canvas又依赖于libstdc++.so.6.24和glibc-2.18,版本必须要对应起来否则报错。2、环境配置好之后将任务配置到crontab,提示 RuntimeUnavailableError('Could not find an available JavaScript runtime.')。原因为crontab的环境只是 /usr/sbin:/usr/bin:/sbin:/bin 没有 /usr/local/bin 。如果把软连接改为ln -s /opt/software/nodejs/bin/node /usr/bin/ 也就不会出现问题了。对应的sh文件如下:
#!/bin/bash#. /etc/profile#. ~/.bash_profile#cd /root/DataCollector/data_collect_py#export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'export PATH='/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'export PYTHONPATH=/root/DataCollector/data_collect_py#export EXECJS_RUNTIME=/opt/software/nodejs/bin/nodeexport DISPLAY=:1<br />/usr/bin/python3 /root/DataCollector/data_collect_py/apps/autotask/run.py -t=125 -pv='548' -jobnum=5482
PS:如有问题欢迎留言~