python寫(xiě)的數據采集,對一般有規律的頁(yè)面用 urllib2 + BeautifulSoup + 正則就可以搞定。 但是有些頁(yè)面的內容是通過(guò)js生成,或者通過(guò)js跳轉的,甚至js中還加入幾道混淆機制;對這種涉及頁(yè)面腳本解析的內容,前面的方式便很無(wú)力。
這時(shí)我們需要能解析、運行js的引擎——瀏覽器,而python selenium能提供程序與瀏覽器的交互接口,再加上phantomjs這個(gè)可以后臺運行的瀏覽器,即使用 selenium + phantomjs 便可以解決以上的問(wèn)題。
selenium可以操作頁(yè)面的元素,并且提供執行js腳本的接口。但其調用js腳本后并不能直接返回執行的結果,這樣再采集內容的過(guò)程中就會(huì )受到一些限制。 比如我們想使用頁(yè)面中的函數進(jìn)行數據轉換,或者獲取iframe里的內容,這些js產(chǎn)生數據要傳回比較麻煩。
所以我便寫(xiě)一個(gè)簡(jiǎn)化js數據回傳的擴展 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="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 執行后有返回值,返回值通過(guò)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')
打開(kāi)ipython上一個(gè)例子,獲取博客園首頁(yè)文章title列表
from selenium import webdriverimport exescriptd=webdriver.PhantomJS("phantomjs")d.get(")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開(kāi)發(fā)點(diǎn)點(diǎn)滴滴之一——DDLogic框架分解上The directfb backend was supported together with linux-fb backend in GTK+2.10Science上發(fā)表的超贊聚類(lèi)算法功能齊全、效率一流的免費開(kāi)源數據庫導入導出工具(c#開(kāi)發(fā),支持SQL server、SQLite、ACCESS三種數據 庫),每月借此處理數據5G以上企業(yè)級應用框架(三)三層架構之數據訪(fǎng)問(wèn)層的改進(jìn)以及測試DOM的發(fā)布Unity3D 第一季 00 深入理解U3D開(kāi)發(fā)平臺Welcome to Swift (蘋(píng)果官方Swift文檔初譯與注解二十一)---140~147頁(yè)(第三章--集合類(lèi)型)appium簡(jiǎn)明教程(11)——使用resource id定位SQL語(yǔ)句匯總(終篇)—— 表聯(lián)接與聯(lián)接查詢(xún)fopen警告處理方式AndroidWear開(kāi)發(fā)之HelloWorld篇AMD and CMD are dead之KMD.js版本0.0.2發(fā)布SQL語(yǔ)句匯總(三)——聚合函數、分組、子查詢(xún)及組合查詢(xún)DevExpress GridControl功能總結ASP.NET之Jquery入門(mén)級別2014年前端面試經(jīng)歷grunt源碼解析:整體運行機制&grunt-cli源碼解析跟用戶(hù)溝通,問(wèn)題盡量分析清楚,以及解決問(wèn)題ASP.NET之Ajax系列(一)算法復雜度分析"""
聯(lián)系客服