selenium在执行phantomjs的API并获取执行结果的方法


Posted in Python onDecember 17, 2018

前言

因为最近要写一个抓取sitemap和相应的参数的小脚本,现有的爬虫无论用什么语言写的,几乎都无法抓取参数,所以我思考了一下,先做一个简单的总结。

本来以为写个这种sitemap的爬虫很简单,经过思考之后才发现其中的可怕之处,最关键的是参数的提取,这个太麻烦了。。。这个时候才发现AWVS的无敌和强大之处。。。

如果我们要获取网站的sitemap同时还要抓取对应链接的参数,我大概总结了url的几个来源:

1、页面上直接现有的form表单以及现有的href等指向的链接及参数,这个相对比较简单,不过要考虑post和get的问题。

2、由js生成的DOM中的form表单和href指向的链接

3、由js发起的访问请求,例如AJAX请求等

4、通过点击然后调用js发送请求,或是点击生成一个form或是生产一个DOM,然后再点击再由js发送请求。例如如下代码

<div>
 <input id="searchTitle" name="searchTitle" value="" type="text">
 <div class="button" onclick="javascript:searchWeb();"></div>
 </div>

5、通过setTimeout函数延迟触发的js的请求,例如setTimeout("request()", 2000);,这一类我暂时还没有太好的办法解决,不过有初步的办法,后面会说到。

目前我大概想到这么五类,肯定还有没考虑到的地方,并且目前实际的代码还没有写出来,我先记录一下我的想法,要是有哪位师傅有兴趣请务必联系我。。。。orz。。

要解决上述的5个问题,因为我的工程的前半部分使用python写的,所以这里我需要用python来解决,那么最佳选择必然是selenium和phantomjs,其实比起来我更想用原生的phantomjs来写。

用phantomjs的话第一个和第二个问题不攻自破,直接正则匹配下来就行了,因为它会帮我们先把页面的js执行了。

第三个问题也相对比较好解决,我们通过原生phantomjs的APIonResourceRequested就能够监控所有从页面发出去的请求。

然后再来看第四个问题,我目前的想法应该没有办法彻底解决,我们同样可以用phantomjs向页面的所有的dom发送一个click事件,但是这样子的话时间是一个很大的问题,所以初步想法向所有具有onclick事件的标签发送点击事件

然后再来看第五个问题,这应该是最麻烦的一个,我初步的想法还是用onResourceRequested事件,然后设置一个超时时限,让页面执行个几秒钟,但是最后我还是放弃了这个想法,我决定忽视这个问题,因为如果每个页面都等上几秒那时间耗费不堆上天了。

以上就是我目前初步的一些思考,还有很多不成熟之处。

selenium与phantomjs联动的问题

之前一直知道有selenium这个东西,不够因为没有地方需要,也没有可以去学习,不过对phantomjs可能会稍微熟悉一些。

先写个简单的程序

from selenium import webdriver
service_args=[]
service_args.append('--load-images=no') ##关闭图片加载
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误

d=webdriver.PhantomJS("phantomjs",service_args=service_args)
d.get("http://xxxxxxxxxxxxxxxxxxxxx")
print d.page_source
d.quit()

这样就可以发送get请求了。

问题一:没有post请求?

我觉得应该是我还了解的不够。不过翻了API,确实没有找到,希望大家能够指出我的错误,但我真的好像没有找到能够发送post请求的地方,真是蠢爆了。。

这里我想到了两种方法解决,先说一种,第二种留到后面说。

就是用requests库递交post请求,拿下来的cookie,调用add_cookie函数给它,然后让它带着cookie发送get请求就好了。

样例如下

from selenium import webdriver
import requests
r=requests.session()

service_args=[]
service_args.append('--load-images=no') ##关闭图片加载
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误

d=webdriver.PhantomJS("phantomjs",service_args=service_args)

data={
 "username":"123",
 "password":"123",
 "login":"1"
 }

result=r.post("http://127.0.0.1:8000/web/login.php",data=data)
cookies=r.cookies.get_dict()
for i in cookies:
 d.add_cookie({
 'name': i,
 'value' :cookies[i],
 'path':'/',
 'domain':'127.0.0.1'
  })
d.get("http://127.0.0.1:8000/web/index.php")
print d.page_source
d.quit()

另外这个add_cookie函数还比较刁钻,还要把path和domain都设置好,不然有时会报错。

第二个方法的话,我们知道,如果用原生PhantomJS的话,我们可以很容易递交post请求,比如如下:

var webPage = require('webpage');
var page = webPage.create();

var settings = {
 operation: "POST",
 header:{},
 data: "username=123&password=123&login=1"
};
page.open('http://127.0.0.1:8000/web/login.php', settings, function(status) {
 //console.log(page.content);
 for(var i=0;i<page.cookies.length;i++){
 console.log(page.cookies[i].name+":"+page.cookies[i].value)
 }
});

所以我们想办法就是直接在 Selenium中让PhantomJS 执行它的 API就可以了,这里不贴了,看完下一小节就知道怎么写了。

问题二:在 Selenium中获取PhantomJS 的API的执行结果?

还好Selenium带了个get_log函数,比如我监控'http://127.0.0.1:8000/web/index.php‘页面向外发送的所有请求,如果用原生的phantomjs,很好办,如下:

var webPage = require('webpage');
var page = webPage.create();

page.onResourceRequested = function (request) {
 console.log('Request ' + request.url);
};
...........
...........

所以我们直接在Selenium中调用PhantomJS 的API就好了。如下

from selenium import webdriver
import requests
r=requests.session()

service_args=[]
service_args.append('--load-images=no') ##关闭图片加载
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误

d=webdriver.PhantomJS("phantomjs",service_args=service_args)

data={
 "username":"123",
 "password":"123",
 "login":"1"
 }

result=r.post("http://127.0.0.1:8000/web/login.php",data=data)
cookies=r.cookies.get_dict()
for i in cookies:
 d.add_cookie({
 'name': i,
 'value' :cookies[i],
 'path':'/',
 'domain':'127.0.0.1'
  })
script = "var page=this;page.onResourceRequested = function (request){console.log(request.url);};"
d.command_executor._commands['executePhantomScript'] = ('POST', '/session/$sessionId/phantom/execute')
d.execute('executePhantomScript', {'script': script, 'args': []})

d.get("http://127.0.0.1:8000/web/index.php")
print d.page_source
d.quit()

这里上述代码确实能够实时执行,但是就这样写的话没有办法获取到结果。

这里需要用到一个get_log函数,改进如下:

from selenium import webdriver
import requests
r=requests.session()

service_args=[]
service_args.append('--load-images=no') ##关闭图片加载
service_args.append('--disk-cache=yes') ##开启缓存
service_args.append('--ignore-ssl-errors=true') ##忽略https错误

d=webdriver.PhantomJS("phantomjs",service_args=service_args)

data={
 "username":"123",
 "password":"123",
 "login":"1"
 }

result=r.post("http://127.0.0.1:8000/web/login.php",data=data)
cookies=r.cookies.get_dict()
for i in cookies:
 d.add_cookie({
 'name': i,
 'value' :cookies[i],
 'path':'/',
 'domain':'127.0.0.1'
  })
script = "var page=this;page.onResourceRequested = function (request){page.browserLog.push(request.url);};"
d.command_executor._commands['executePhantomScript'] = ('POST', '/session/$sessionId/phantom/execute')
d.execute('executePhantomScript', {'script': script, 'args': []})

d.get("http://127.0.0.1:8000/web/index.php")
print d.page_source
print d.get_log('browser')
d.quit()

在js脚本中我们调用page.browserLog.push,然后在python脚本中我们get_log('browser')去获取就可以实现相互沟通,当然肯定还有别的办法,不过我没有找到。。。。僵硬了。。。。

后记

再说这个抓取sitemap和请求参数的小脚本,想了想还是觉得非常麻烦,虽然几个问题都有了相应的解决办法,也不管好坏,加上今天稍微研究了一下python调用phantom的优化,还是稍微有点信心了,但是感觉要整合到一起来还是会很麻烦,效率问题是一个,能否真正准确抓取完整又是另一个,慢慢来把,没想到最初觉得不是问题的问题最后却成了我最大的麻烦之一。。僵硬。。。最后还要说的是原声的phantomjs真的比selenium去调用舒服得多。。。现在想来要是最开始想把每个环节思考一下就好了,要是思考了大概就不会用python了,大概会用nodejs,对了,最近稍微研究了一下nodejs的一些渗透和攻击方法,后续整理一下分享出来,希望师傅们能够帮忙指点指点。

以上这篇selenium在执行phantomjs的API并获取执行结果的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 排列组合之itertools
Mar 20 Python
python实现的一个火车票转让信息采集器
Jul 09 Python
python 添加用户设置密码并发邮件给root用户
Jul 25 Python
pandas 数据归一化以及行删除例程的方法
Nov 10 Python
python简易实现任意位数的水仙花实例
Nov 13 Python
python 中pyqt5 树节点点击实现多窗口切换问题
Jul 04 Python
Kali Linux安装ipython2 和 ipython3的方法
Jul 11 Python
pycharm重命名文件的方法步骤
Jul 29 Python
softmax及python实现过程解析
Sep 30 Python
浅析Python 抽象工厂模式的优缺点
Jul 13 Python
Python实现一个论文下载器的过程
Jan 18 Python
如何使用PyCharm及常用配置详解
Jun 03 Python
Python脚本完成post接口测试的实例
Dec 17 #Python
python:接口间数据传递与调用方法
Dec 17 #Python
python直接获取API传递回来的参数方法
Dec 17 #Python
python获取url的返回信息方法
Dec 17 #Python
Pycharm配置远程调试的方法步骤
Dec 17 #Python
Python解析、提取url关键字的实例详解
Dec 17 #Python
Django Rest framework之认证的实现代码
Dec 17 #Python
You might like
虫族 Zerg 魔法科技
2020/03/14 星际争霸
基于PHP+MySQL的聊天室设计
2006/10/09 PHP
坏狼的PHP学习教程之第1天
2008/06/15 PHP
解析yahoo邮件用phpmailer发送的实例
2013/06/24 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
Add Formatted Text to a Word Document
2007/06/15 Javascript
js判断变量是否空值的代码
2008/10/26 Javascript
jquery的冒泡事件的阻止与允许(三种实现方法)
2013/02/01 Javascript
关于jQuery object and DOM element
2013/04/15 Javascript
Javascript Web Slider 焦点图示例源码
2013/10/10 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
jQuery ajax serialize() 方法使用示例
2014/11/02 Javascript
node.js中的fs.exists方法使用说明
2014/12/17 Javascript
JavaScript中函数(Function)的apply与call理解
2015/07/08 Javascript
详解JavaScript对象类型
2016/06/16 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
2017/05/02 Javascript
BootStrap 标题设置跨行无效的解决方法
2017/10/25 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
微信小程序拍照和摄像功能实现方法示例
2019/02/01 Javascript
ES6中的class是如何实现的(附Babel编译的ES5代码详解)
2019/05/17 Javascript
解决layui追加或者动态修改的表单元素“没效果”的问题
2019/09/18 Javascript
python和shell变量互相传递的几种方法
2013/11/20 Python
实例讲解Python中的私有属性
2014/08/21 Python
Python 文件管理实例详解
2015/11/10 Python
Python基于scapy实现修改IP发送请求的方法示例
2017/07/08 Python
Django admin美化插件suit使用示例
2017/12/12 Python
Python 文件操作之读取文件(read),文件指针与写入文件(write),文件打开方式示例
2019/09/29 Python
python生成器用法实例详解
2019/11/22 Python
详解Django关于StreamingHttpResponse与FileResponse文件下载的最优方法
2021/01/07 Python
瑞典灯具和照明网上商店:Lamp24.se
2018/03/17 全球购物
Bally澳大利亚官网:瑞士奢侈品牌
2018/11/01 全球购物
公司经理聘任书
2014/03/29 职场文书
vue如何批量引入组件、注册和使用详解
2021/05/12 Vue.js
TensorFlow的自动求导原理分析
2021/05/26 Python
Python 居然可以在 Excel 中画画你知道吗
2022/02/15 Python
virtualenv隔离Python环境的问题解析
2022/06/21 Python