php抓取动态页面数据
为了安全性问题,很多网页会动态生成一些数据,当提交表单的时候会将这些数据提交服务端,然后在服务端进行校验。当遇到这类问题时,可以使用phantomjs或selenium模拟浏览器行为加载js脚本,获取动态数据。以京东模拟登陆(仅以学习为目的)为例:
京东模拟登陆
通过开发者工具Network分析网络请求数据可得京东登陆接口:
所需参数如下:
页面源码如下:
开发者工具Elements如下:
经尝试可得eid与fp需引入js脚本方可获取其值。若仅使用curl抓取该页面数据,则无法抓取所需的所有数据。为此,使用phantomjs或selenium模拟浏览器行为加载js脚本。
phantomjs
下载链接:phantomjs download
quick start:phantomjs quick start
使用phantomjs加载js脚本文件
load.js:
1 | var page = require('webpage').create(); |
上述代码将页面代码以字符串的形式返回。
调用phantomjs脚本
exec(‘phantomjs load.js’, $output);
exec()函数说明:
1 | string exec ( string $command [, array &$output [, int &$return_var ]] ) |
exec() 执行 command 参数所指定的命令。
command
要执行的命令。
output
如果提供了 output 参数,那么会用命令执行的输出填充此数组,每行输出填充数组中的一个元素。数组中的数据不包含行尾的空白字符,例如 \n 字符。请注意,如果数组中已经包含了部分元素,exec() 函数会在数组末尾追加内容。如果你不想在数组末尾进行追加,请在传入 exec() 函数之前对数组使用 unset() 函数进行重置。
return_var
如果同时提供 output 和 return_var 参数,命令执行后的返回状态会被写入到此变量。
返回值
命令执行结果的最后一行内容。如果想要获取命令的输出内容,请确保使用 output 参数。
至此,可通过preg_match函数对源码进行模式匹配,提取出需要的数据。利用php curl扩展模拟post请求。
post参数被加密怎么办?
如密码字段使用JSEncrypt库加密后再向服务端请求,这时可以使用phantomjs调用该js库,获取加密后的密码字符串,示例代码如下:
encrypt.js:
1 | var page = require('webpage').create(); |
终端运行:
1 | $ phantomjs encrypt.js args1 args2 |
require(‘system’)获取命令行脚本参数,以此可以将php内的变量值传递进来,同上用exec()执行该命令行脚本,即可获取加密后的密码字段。
总结
当需要抓取动态网页数据时,可以使用phantomjs和selenium模拟浏览器行为加载js文件。