selenium在執(zhí)行phantomjs的API并獲取執(zhí)行結(jié)果的方法
前言
因?yàn)樽罱獙懸粋€(gè)抓取sitemap和相應(yīng)的參數(shù)的小腳本,現(xiàn)有的爬蟲無論用什么語言寫的,幾乎都無法抓取參數(shù),所以我思考了一下,先做一個(gè)簡(jiǎn)單的總結(jié)。
本來以為寫個(gè)這種sitemap的爬蟲很簡(jiǎn)單,經(jīng)過思考之后才發(fā)現(xiàn)其中的可怕之處,最關(guān)鍵的是參數(shù)的提取,這個(gè)太麻煩了。。。這個(gè)時(shí)候才發(fā)現(xiàn)AWVS的無敵和強(qiáng)大之處。。。
如果我們要獲取網(wǎng)站的sitemap同時(shí)還要抓取對(duì)應(yīng)鏈接的參數(shù),我大概總結(jié)了url的幾個(gè)來源:
1、頁面上直接現(xiàn)有的form表單以及現(xiàn)有的href等指向的鏈接及參數(shù),這個(gè)相對(duì)比較簡(jiǎn)單,不過要考慮post和get的問題。
2、由js生成的DOM中的form表單和href指向的鏈接
3、由js發(fā)起的訪問請(qǐng)求,例如AJAX請(qǐng)求等
4、通過點(diǎn)擊然后調(diào)用js發(fā)送請(qǐng)求,或是點(diǎn)擊生成一個(gè)form或是生產(chǎn)一個(gè)DOM,然后再點(diǎn)擊再由js發(fā)送請(qǐng)求。例如如下代碼
<div> <input id="searchTitle" name="searchTitle" value="" type="text"> <div class="button" onclick="javascript:searchWeb();"></div> </div>
5、通過setTimeout函數(shù)延遲觸發(fā)的js的請(qǐng)求,例如setTimeout("request()", 2000);,這一類我暫時(shí)還沒有太好的辦法解決,不過有初步的辦法,后面會(huì)說到。
目前我大概想到這么五類,肯定還有沒考慮到的地方,并且目前實(shí)際的代碼還沒有寫出來,我先記錄一下我的想法,要是有哪位師傅有興趣請(qǐng)務(wù)必聯(lián)系我。。。。orz。。
要解決上述的5個(gè)問題,因?yàn)槲业墓こ痰那鞍氩糠质褂胮ython寫的,所以這里我需要用python來解決,那么最佳選擇必然是selenium和phantomjs,其實(shí)比起來我更想用原生的phantomjs來寫。
用phantomjs的話第一個(gè)和第二個(gè)問題不攻自破,直接正則匹配下來就行了,因?yàn)樗鼤?huì)幫我們先把頁面的js執(zhí)行了。
第三個(gè)問題也相對(duì)比較好解決,我們通過原生phantomjs的APIonResourceRequested就能夠監(jiān)控所有從頁面發(fā)出去的請(qǐng)求。
然后再來看第四個(gè)問題,我目前的想法應(yīng)該沒有辦法徹底解決,我們同樣可以用phantomjs向頁面的所有的dom發(fā)送一個(gè)click事件,但是這樣子的話時(shí)間是一個(gè)很大的問題,所以初步想法向所有具有onclick事件的標(biāo)簽發(fā)送點(diǎn)擊事件
然后再來看第五個(gè)問題,這應(yīng)該是最麻煩的一個(gè),我初步的想法還是用onResourceRequested事件,然后設(shè)置一個(gè)超時(shí)時(shí)限,讓頁面執(zhí)行個(gè)幾秒鐘,但是最后我還是放棄了這個(gè)想法,我決定忽視這個(gè)問題,因?yàn)槿绻總€(gè)頁面都等上幾秒那時(shí)間耗費(fèi)不堆上天了。
以上就是我目前初步的一些思考,還有很多不成熟之處。
selenium與phantomjs聯(lián)動(dòng)的問題
之前一直知道有selenium這個(gè)東西,不夠因?yàn)闆]有地方需要,也沒有可以去學(xué)習(xí),不過對(duì)phantomjs可能會(huì)稍微熟悉一些。
先寫個(gè)簡(jiǎn)單的程序
from selenium import webdriver service_args=[] service_args.append('--load-images=no') ##關(guān)閉圖片加載 service_args.append('--disk-cache=yes') ##開啟緩存 service_args.append('--ignore-ssl-errors=true') ##忽略https錯(cuò)誤 d=webdriver.PhantomJS("phantomjs",service_args=service_args) d.get("http://xxxxxxxxxxxxxxxxxxxxx") print d.page_source d.quit()
這樣就可以發(fā)送get請(qǐng)求了。
問題一:沒有post請(qǐng)求?
我覺得應(yīng)該是我還了解的不夠。不過翻了API,確實(shí)沒有找到,希望大家能夠指出我的錯(cuò)誤,但我真的好像沒有找到能夠發(fā)送post請(qǐng)求的地方,真是蠢爆了。。
這里我想到了兩種方法解決,先說一種,第二種留到后面說。
就是用requests庫遞交post請(qǐng)求,拿下來的cookie,調(diào)用add_cookie函數(shù)給它,然后讓它帶著cookie發(fā)送get請(qǐng)求就好了。
樣例如下
from selenium import webdriver import requests r=requests.session() service_args=[] service_args.append('--load-images=no') ##關(guān)閉圖片加載 service_args.append('--disk-cache=yes') ##開啟緩存 service_args.append('--ignore-ssl-errors=true') ##忽略https錯(cuò)誤 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()
另外這個(gè)add_cookie函數(shù)還比較刁鉆,還要把path和domain都設(shè)置好,不然有時(shí)會(huì)報(bào)錯(cuò)。
第二個(gè)方法的話,我們知道,如果用原生PhantomJS的話,我們可以很容易遞交post請(qǐng)求,比如如下:
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 執(zhí)行它的 API就可以了,這里不貼了,看完下一小節(jié)就知道怎么寫了。
問題二:在 Selenium中獲取PhantomJS 的API的執(zhí)行結(jié)果?
還好Selenium帶了個(gè)get_log函數(shù),比如我監(jiān)控'http://127.0.0.1:8000/web/index.php‘頁面向外發(fā)送的所有請(qǐng)求,如果用原生的phantomjs,很好辦,如下:
var webPage = require('webpage'); var page = webPage.create(); page.onResourceRequested = function (request) { console.log('Request ' + request.url); }; ........... ...........
所以我們直接在Selenium中調(diào)用PhantomJS 的API就好了。如下
from selenium import webdriver import requests r=requests.session() service_args=[] service_args.append('--load-images=no') ##關(guān)閉圖片加載 service_args.append('--disk-cache=yes') ##開啟緩存 service_args.append('--ignore-ssl-errors=true') ##忽略https錯(cuò)誤 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()
這里上述代碼確實(shí)能夠?qū)崟r(shí)執(zhí)行,但是就這樣寫的話沒有辦法獲取到結(jié)果。
這里需要用到一個(gè)get_log函數(shù),改進(jìn)如下:
from selenium import webdriver import requests r=requests.session() service_args=[] service_args.append('--load-images=no') ##關(guān)閉圖片加載 service_args.append('--disk-cache=yes') ##開啟緩存 service_args.append('--ignore-ssl-errors=true') ##忽略https錯(cuò)誤 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腳本中我們調(diào)用page.browserLog.push,然后在python腳本中我們get_log('browser')去獲取就可以實(shí)現(xiàn)相互溝通,當(dāng)然肯定還有別的辦法,不過我沒有找到。。。。僵硬了。。。。
后記
再說這個(gè)抓取sitemap和請(qǐng)求參數(shù)的小腳本,想了想還是覺得非常麻煩,雖然幾個(gè)問題都有了相應(yīng)的解決辦法,也不管好壞,加上今天稍微研究了一下python調(diào)用phantom的優(yōu)化,還是稍微有點(diǎn)信心了,但是感覺要整合到一起來還是會(huì)很麻煩,效率問題是一個(gè),能否真正準(zhǔn)確抓取完整又是另一個(gè),慢慢來把,沒想到最初覺得不是問題的問題最后卻成了我最大的麻煩之一。。僵硬。。。最后還要說的是原聲的phantomjs真的比selenium去調(diào)用舒服得多。?!,F(xiàn)在想來要是最開始想把每個(gè)環(huán)節(jié)思考一下就好了,要是思考了大概就不會(huì)用python了,大概會(huì)用nodejs,對(duì)了,最近稍微研究了一下nodejs的一些滲透和攻擊方法,后續(xù)整理一下分享出來,希望師傅們能夠幫忙指點(diǎn)指點(diǎn)。
以上這篇selenium在執(zhí)行phantomjs的API并獲取執(zhí)行結(jié)果的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Selenium執(zhí)行Javascript腳本參數(shù)及返回值過程詳解
- Python爬蟲圖片懶加載技術(shù) selenium和PhantomJS解析
- python爬蟲selenium和phantomJs使用方法解析
- 詳解Selenium+PhantomJS+python簡(jiǎn)單實(shí)現(xiàn)爬蟲的功能
- selenium設(shè)置proxy、headers的方法(phantomjs、Chrome、Firefox)
- Python爬蟲使用Selenium+PhantomJS抓取Ajax和動(dòng)態(tài)HTML內(nèi)容
- C#使用Selenium+PhantomJS抓取數(shù)據(jù)
- 如何在selenium中使用js實(shí)現(xiàn)定位
相關(guān)文章
python實(shí)現(xiàn)對(duì)圖片進(jìn)行旋轉(zhuǎn),放縮,裁剪的功能
今天小編就為大家分享一篇python實(shí)現(xiàn)對(duì)圖片進(jìn)行旋轉(zhuǎn),放縮,裁剪的功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08盤點(diǎn)20個(gè)Python數(shù)據(jù)科學(xué)庫神器打造數(shù)據(jù)魔法世界
數(shù)據(jù)科學(xué)家和分析師常常使用?Python?來處理數(shù)據(jù)、進(jìn)行分析和可視化,Python生態(tài)系統(tǒng)中有許多庫,但有一些庫是數(shù)據(jù)科學(xué)家日常工作中必不可少的,本文將深入介紹20個(gè)重要的Python?庫,包括示例代碼和用例2024-01-01淺析Python中壓縮zipfile與解壓縮tarfile模塊的使用
Python?提供了兩個(gè)標(biāo)準(zhǔn)庫模塊來處理文件的壓縮和解壓縮操作:zipfile和tarfile,本文將分享?這兩個(gè)模塊的使用方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10python中set()函數(shù)簡(jiǎn)介及實(shí)例解析
這篇文章主要介紹了python中set()函數(shù)簡(jiǎn)介及實(shí)例解析,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01以911新聞為例演示Python實(shí)現(xiàn)數(shù)據(jù)可視化的教程
這篇文章主要介紹了以911新聞為例演示Python實(shí)現(xiàn)數(shù)據(jù)可視化的教程,主要基于NMF主題模型,需要的朋友可以參考下2015-04-04