日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Python selenium的js擴展實現(xiàn)

 看見就非常 2015-09-18

python寫的數(shù)據(jù)采集,對一般有規(guī)律的頁面用 urllib2 + BeautifulSoup + 正則就可以搞定。 但是有些頁面的內(nèi)容是通過js生成,或者通過js跳轉(zhuǎn)的,甚至js中還加入幾道混淆機制;對這種涉及頁面腳本解析的內(nèi)容,前面的方式便很無力。

這時我們需要能解析、運行js的引擎——瀏覽器,而python selenium能提供程序與瀏覽器的交互接口,再加上phantomjs這個可以后臺運行的瀏覽器,即使用 selenium + phantomjs 便可以解決以上的問題。

selenium可以操作頁面的元素,并且提供執(zhí)行js腳本的接口。但其調(diào)用js腳本后并不能直接返回執(zhí)行的結果,這樣再采集內(nèi)容的過程中就會受到一些限制。 比如我們想使用頁面中的函數(shù)進行數(shù)據(jù)轉(zhuǎn)換,或者獲取iframe里的內(nèi)容,這些js產(chǎn)生數(shù)據(jù)要傳回比較麻煩。

所以我便寫一個簡化js數(shù)據(jù)回傳的擴展 exescript.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# created by heqingpan

_init_js="""
(function (){
if (window.__e)
{ return;
}
var e=document.createElement('div');
e.setAttribute("id","__s_msg");
e.style.display="none";
document.body.appendChild(e);
window.__e=e;
})();
window.__s_set_msg=function(a){
    window.__e.setAttribute("msg",a.toString()||"");
}
"""
_loadJsFmt="""
var script = document.createElement('script');
script.src = "{0}";
document.body.appendChild(script);
"""
_jquery_cdn="
_warpjsfmt="__s_set_msg({0})"

class ExeJs(object):
    def __init__(self,driver,trytimes=10):
        from time import sleep
        self.driver=driver
        driver.execute_script(_init_js)
        while trytimes >0:
            try:
                self.msgNode=driver.find_element_by_id('__s_msg')
                break
            except Exception:
                sleep(1)
                trytimes -= 1
        if self.msgNode is None:
            raise Exception()
    def exeWrap(self,jsstr):
        """ jsstr 執(zhí)行后有返回值,返回值通過self.getMsg()獲取 """
        self.driver.execute_script(_warpjsfmt.format(jsstr))
    def loadJs(self,path):
        self.execute(_loadJsFmt.format(path))
    def loadJquery(self,path=_jquery_cdn):
        self.loadJs(path)
    def execute(self,jsstr):
        self.driver.execute_script(jsstr)
    def getMsg(self):
        return self.msgNode.get_attribute('msg')

打開ipython上一個例子,獲取博客園首頁文章title列表

from selenium import webdriver
import exescript

d=webdriver.PhantomJS("phantomjs")
d.get(")
exejs=exescript.ExeJs(d)
exejs.exeWrap('$(".post_item").length')
print exejs.getMsg()
#out: 
"""
20
"""

jsstr="""(function(){
var r=[];
$(".post_item").each(function(){
  var $this=$(this);
  var $h3=$this.find("h3");
  r.push($h3.text());
});
return r.join(',');})()"""
exejs.exeWrap(jsstr)
l=exejs.getMsg()
for title in l.split(','):
    print title

#out:
"""
mac TeamTalk開發(fā)點點滴滴之一——DDLogic框架分解上
The directfb backend was supported together with linux-fb backend in GTK+2.10
Science上發(fā)表的超贊聚類算法
功能齊全、效率一流的免費開源數(shù)據(jù)庫導入導出工具(c#開發(fā),支持SQL server、SQLite、ACCESS三種數(shù)據(jù)  庫),每月借此處理數(shù)據(jù)5G以上
企業(yè)級應用框架(三)三層架構之數(shù)據(jù)訪問層的改進以及測試DOM的發(fā)布
Unity3D 第一季 00 深入理解U3D開發(fā)平臺
Welcome to Swift (蘋果官方Swift文檔初譯與注解二十一)---140~147頁(第三章--集合類型)
appium簡明教程(11)——使用resource id定位
SQL語句匯總(終篇)—— 表聯(lián)接與聯(lián)接查詢
fopen警告處理方式
AndroidWear開發(fā)之HelloWorld篇
AMD and CMD are dead之KMD.js版本0.0.2發(fā)布
SQL語句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
DevExpress GridControl功能總結
ASP.NET之Jquery入門級別
2014年前端面試經(jīng)歷
grunt源碼解析:整體運行機制&grunt-cli源碼解析
跟用戶溝通,問題盡量分析清楚,以及解決問題
ASP.NET之Ajax系列(一)
算法復雜度分析
"""

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多