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 相关文章推荐
django 自定义用户user模型的三种方法
Nov 18 Python
python中__slots__用法实例
Jun 04 Python
Python验证码识别的方法
Jul 10 Python
Python获取某一天是星期几的方法示例
Jan 17 Python
Python中模块pymysql查询结果后如何获取字段列表
Jun 05 Python
python里使用正则的findall函数的实例详解
Oct 19 Python
Python中property属性实例解析
Feb 10 Python
python 抓包保存为pcap文件并解析的实例
Jul 23 Python
python cv2截取不规则区域图片实例
Dec 21 Python
python 实现汉诺塔游戏
Nov 28 Python
Python实现排序方法常见的四种
Jul 15 Python
Python中第三方库Faker的使用详解
Apr 02 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
根德YB400的电路分析
2021/03/02 无线电
php+mysql实现无限级分类 | 树型显示分类关系
2006/11/19 PHP
php获取当前月与上个月月初及月末时间戳的方法
2016/12/05 PHP
PHP实现微信对账单处理
2018/10/01 PHP
Laravel实现ORM带条件搜索分页
2019/10/24 PHP
jQuery 研究心得 取得属性的值
2007/11/30 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
jquery实现弹出窗口效果的实例代码
2013/11/28 Javascript
防止jQuery ajax Load使用缓存的方法小结
2014/02/22 Javascript
JS判断是否长按某一键的方法
2016/03/02 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
2016/06/06 Javascript
详解Vue.js——60分钟组件快速入门(上篇)
2016/12/05 Javascript
js读取本地文件的实例
2017/12/22 Javascript
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
js中的 || 与 &amp;&amp; 运算符详解
2018/05/24 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【矩形情况】
2018/12/13 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
Python函数式编程指南(三):迭代器详解
2015/06/24 Python
python简单实现获取当前时间
2016/08/27 Python
速记Python布尔值
2017/11/09 Python
用不到50行的Python代码构建最小的区块链
2017/11/16 Python
对Python 数组的切片操作详解
2018/07/02 Python
pyqt5 删除layout中的所有widget方法
2019/06/25 Python
Django admin组件的使用
2020/10/24 Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
2020/11/29 Python
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
会计职业生涯规划范文
2014/01/04 职场文书
上班早退检讨书
2014/01/09 职场文书
市场开发计划书
2014/05/07 职场文书
植树造林的宣传标语
2014/06/23 职场文书
幼儿园大班开学寄语
2014/08/02 职场文书
合伙购房协议样本
2014/10/06 职场文书
小王子读书笔记
2015/06/29 职场文书
Python 的 sum() Pythonic 的求和方法详细
2021/10/16 Python
Python中time标准库的使用教程
2022/04/13 Python
Golang解析JSON对象
2022/04/30 Golang