python 调用js_Python调用JavaScript代码

在写爬虫经常会遇到很多JS代码,比如说某些参数加密,可以只用用Python来翻译,但是有时候代码不容易阅读(JS渣渣),所以这里直接去找一条捷径,直接用Python的第三方库去调用JS代码。

这里用到的是 execjs

安装

虽然这个库导入名是import execjs,但是安装名却不是。安装方式如下:

$ pip install PyExecJS

使用

官方的例子

>>> import execjs

>>> execjs.eval("'red yellow blue'.split(' ')")

['red', 'yellow', 'blue']

>>> ctx = execjs.compile("""... function add(x, y) {... return x + y;... }... """)

>>> ctx.call("add", 1, 2)

3

用法很简单,execjs.compile后面就是JS源码,然后使用ctx.call来调用,参数就是JS中定义的函数名,同时可以传递参数。

作者也有说到:PyExecJS的优点是您不需要处理JavaScript环境。 特别是,它可以在Windows环境中运行,无需安装额外的库。

PyExecJS的一个缺点是性能。 PyExecJS通过文本传递JavaScript运行时,速度很慢。 另一个缺点是它不完全支持运行时特定功能。

看了下源码,执行过程大概是这样。

首先用compile来编译JS代码:

def compile(source, cwd=None):

return get().compile(source, cwd)

编译代码:

def _compile(self, source, cwd=None):

return self.Context(self, source, cwd=cwd, tempfile=self._tempfile)

然后call来执行:

def call(self, name, *args):

'''Call a JavaScript function in context.name -- Name of funtion object to callargs -- Arguments for the funtion object'''

if not self.is_available():

raise execjs.RuntimeUnavailableError

return self._call(name, *args)

###

def _call(self, identifier, *args):

args = json.dumps(args)

return self._eval("{identifier}.apply(this,{args})".format(identifier=identifier, args=args))

###

def _eval(self, source):

if not source.strip():

data = "''"

else:

data = "'('+" + json.dumps(source, ensure_ascii=True) + "+')'"

code = 'return eval({data})'.format(data=data)

return self.exec_(code)

###

def _compile(self, source):

runner_source = self._runtime._runner_source

replacements = {

'#{source}': lambda: source,

'#{encoded_source}': lambda: json.dumps(

"(function(){ " +

encode_unicode_codepoints(source) +

" })()"

),

'#{json2_source}': _json2._json2_source,

}

pattern = "|".join(re.escape(k) for k in replacements)

runner_source = re.sub(pattern, lambda m: replacements[m.group(0)](), runner_source)

return runner_source

实例

function generateUUID() {

var d = (new Date).getTime()

, a = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(a) {

var r = (d + 16 * Math.random()) % 16 | 0;

return d = Math.floor(d / 16),

("x" == a ? r : 7 & r | 8).toString(16)

});

return a

}

例如有上面这段JS,我目前不清楚如何去翻译,所以直接偷懒:

def generate_uuid():

js = """function generateUUID() {var d = (new Date).getTime(), a = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(a) {var r = (d + 16 * Math.random()) % 16 | 0;return d = Math.floor(d / 16),("x" == a ? r : 7 & r | 8).toString(16)});return a}"""

ctx = execjs.compile(js)

return ctx.call("generateUUID")

JS大佬可以试试翻译一波。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值