博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Python中执行javascript
阅读量:6368 次
发布时间:2019-06-23

本文共 1966 字,大约阅读时间需要 6 分钟。

在使用python抓取网页的过程中,有的时候需要执行某些简单的javascript,以获得自己需要的内容,例如执行js里面的document.write或者document.getElementById等。自己解析js代码显然有点吃力不讨好,因此最好能找到一些可以解析执行js的python库。

google之可以找到三个候选者,分别是微软的ScriptControl,v8的python移植,还有SpiderMonkey的Python移植。其中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.clientclass win32Doc:     _public_methods_ = ['write']     def write(self, s):             print sdoc = win32Doc()jsengine = win32com.client.Dispatch('MSScriptControl.ScriptControl')jsengine.language = 'JavaScript'jsengine.allowUI = Falsejsengine.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 PyV8class 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 Linuxctxt.eval(u'document.write("你好,中国")'.encode('utf-8'))

上面只是在python里模拟执行js的document.write的大体思路,如果还需要执行其他的js代码对DOM树进行操纵,那就一个个添加对应的方法好了。当然,这个添加也要保持一个限度,不然添加的方法太多,代码会非常复杂,相当于自己已经开始实现一个DOM树处理和解析的完全封装了,如果是这样,还不如使用自动化接口操纵浏览器,例如通过js/vbs操纵IE,或者在后台进行自动化批处理的话,使用一些headless browser软件,例如,这就留待以后再说了。

转载地址:http://vrema.baihongyu.com/

你可能感兴趣的文章
重置 radio 和 checkbox 的样式
查看>>
Android实战简易教程-第二十三枪(基于Baas的用户注冊和登录模块实现!)
查看>>
oc59--匿名分类
查看>>
redis 持久化
查看>>
机器学习算法总结
查看>>
高效的找出两个List中的不同元素
查看>>
Revit二次钢筋
查看>>
Vertx简介
查看>>
项目经理在项目各阶段的工作重点-更新版
查看>>
s3c2440中U-boot移植时执行cp.b提示:Flash not Erased【转】
查看>>
docker Redis的主从配置
查看>>
博文参考:Java编程中“为了性能”尽量要做到的一些地方
查看>>
【JAVASCRIPT】jquery实现ajax无刷新评论
查看>>
flex---->MXML语法
查看>>
mysql日志设置优化
查看>>
安装oracle遇到的故障
查看>>
进一步了解String
查看>>
centos6 yum安装nginx、php-fpm
查看>>
OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较...
查看>>
linux内核模块编译
查看>>