在Python中執行javascript


在Python中執行javascript - 熊貓凶猛 - 博客園

在Python中執行javascript

在使用python抓取網頁的過程中,有的時候需要執行某些簡單的javascript,以獲得自己需要的內容,例如執行js里面的document.write或者document.getElementById等。自己解析js代碼顯然有點吃力不討好,因此最好能找到一些可以解析執行js的python庫。

google之可以找到三個候選者,分別是微軟的ScriptControl,v8的python移植PyV8,還有SpiderMonkey的Python移植Python-Spidermonkey。其中ScriptControl只能在windows上運行,需要win32com庫;PyV8能在windows和*nix上運行,但是需要裝PyV8庫;而SpiderMonkey是mozilla的js引擎在python上的移植,感覺已經不太活躍,因此沒用。

微軟的ScriptControl中對執行js最重要的方法就是addObject與eval,通過addObject,我們可以向js執行環境注入一個我們自定義的document對象,通過eval方法,我們可以執行一段js代碼。注入自定義對象需要使用win32com.server.util.wrap方法,將一個python對象包裝為COM對象,例如假設我們想注入一個只實現了write方法的document對象,代碼是這樣的:

復制代碼
import win32com.server.util, win32com.client

class win32Doc:
     _public_methods_ = ['write']
     def write(self, s):
             print s

doc = win32Doc()
jsengine = win32com.client.Dispatch('MSScriptControl.ScriptControl')
jsengine.language = 'JavaScript'
jsengine.allowUI = False
jsengine.addObject('document', win32com.server.util.wrap(doc))
jsengine.eval('document.write("hello, world")')
復制代碼

在windows里運行這段python代碼,最終就會打印出hello, world來。如果我們希望從python里讀取js通過document.write寫入的字符串並進行解析,只要給上面的win32Doc類添加對應的方法(例如read),就可以讀取並解析HTML代碼,並進行進一步處理了。

對PyV8來說,原理也是類似的,不過在具體機制上有所不同而已。在PyV8中需要在初始化的時候加入一個全局對象,其他的對象都是掛在全局對象之下的,例如document只是全局對象的一個屬性而已(實際上,document對象就是window對象的一個屬性么),當然,這個屬性對應的實際上是一個對象。需要注意的是,PyV8在處理字符串編碼的時候讓人很迷惑,在windows下它需要js的編碼為UTF8,而在Linux下只要求寬字符串,即python里的unicode,而在內部的字符串都是UTF8編碼的。至於為何如此,熊貓也騷擾過開發PyV8的flier,貌似是V8自己的feature。示例代碼是這樣的:

復制代碼
import PyV8

class v8Doc(PyV8.JSClass):
     def write(self, s):
             print s.decode('utf-8')

class Global(PyV8.JSClass):
     def __init__(self):
             self.document = v8Doc()

glob = Global()
ctxt = PyV8.JSContext(glob)
ctxt.enter()
#or ctxt.eval(u'document.write("你好,中國")') for Linux
ctxt.eval(u'document.write("你好,中國")'.encode('utf-8'))
復制代碼

上面只是在python里模擬執行js的document.write的大體思路,如果還需要執行其他的js代碼對DOM樹進行操縱,那就一個個添加對應的方法好了。當然,這個添加也要保持一個限度,不然添加的方法太多,代碼會非常復雜,相當於自己已經開始實現一個DOM樹處理和解析的完全封裝了,如果是這樣,還不如使用自動化接口操縱瀏覽器,例如通過js/vbs操縱IE,或者在后台進行自動化批處理的話,使用一些headless browser軟件,例如phantomjs,這就留待以后再說了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM