Как оценить код JavaScript в Python - PullRequest
6 голосов
/ 02 мая 2010

Мне нужно получить какой-то результат на веб-странице, которая использует код JavaScript для генерации интересующей меня части, например:

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||c;k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('5 11=17;5 12=["/3/2/1/0/13.4","/3/2/1/0/15.4","/3/2/1/0/14.4","/3/2/1/0/7.4","/3/2/1/0/6.4","/3/2/1/0/8.4","/3/2/1/0/10.4","/3/2/1/0/9.4","/3/2/1/0/23.4","/3/2/1/0/22.4","/3/2/1/0/24.4","/3/2/1/0/26.4","/3/2/1/0/25.4","/3/2/1/0/18.4","/3/2/1/0/16.4","/3/2/1/0/19.4","/3/2/1/0/21.4"];5 20=0;',10,27,'40769|54|Images|Files|png|var|imanhua_005_140430179|imanhua_004_140430179|imanhua_006_140430226|imanhua_008_140430242|imanhua_007_140430226|len|pic|imanhua_001_140429664|imanhua_003_140430117|imanhua_002_140430070|imanhua_015_140430414||imanhua_014_140430382|imanhua_016_140430414|sid|imanhua_017_140430429|imanhua_010_140430289|imanhua_009_140430242|imanhua_011_140430367|imanhua_013_140430382|imanhua_012_140430367'.split('|'),0,{}))

Результат eval() важен для меня, я пишу скрипт на Python, есть ли какая-либо библиотека, которую я могу использовать для виртуального запуска этого фрагмента кода JavaScript и получения вывода?

Спасибо

Ответы [ 6 ]

9 голосов
/ 02 мая 2010

pyv8 - это набор привязок для JavaScript-движка V8 (Google Chrome)

6 голосов
/ 02 мая 2010

Использовать привязку spidermonkey

from spidermonkey import Runtime
rt = Runtime()
cx = rt.new_context()
result = cx.eval_script(whatyoupostedabove)
4 голосов
/ 02 мая 2010

Вы можете использовать PyQt с модулем WebKit :) Он имеет JS-движок и может оценивать JS в контексте (X) HTML-документа.

2 голосов
/ 13 мая 2011

Полагаю, вы уже решили проблему, но я хотел бы поделиться другим (на мой взгляд, гораздо более жизнеспособным) вариантом. Если вы заинтересованы в оценке только одной функции --known-- javascript, может быть проще реализовать эту функцию в Python, чем использовать огромный инструмент, созданный для анализа и запуска всего мыслимого javascript в мире.

Так что я бы предложил написать Python-версию функции распаковщика javascript, и большинство из них решено. Я действительно сделал это, и вот пример. Функция int2base - это реализация Алекса Мартелли, которую можно найти здесь .

def unpack(p, a, c, k, e=None, d=None):
    ''' unpack
    Unpacker for the popular Javascript compression algorithm.

    @param  p  template code
    @param  a  radix for variables in p
    @param  c  number of variables in p
    @param  k  list of c variable substitutions
    @param  e  not used
    @param  d  not used
    @return p  decompressed string
    '''
    # Paul Koppen, 2011
    for i in xrange(c-1,-1,-1):
        if k[i]:
            p = re.sub('\\b'+int2base(i,a)+'\\b', k[i], p)
    return p

Наконец, вам нужно немного разобрать, чтобы извлечь четыре аргумента функции. Просто для простоты иллюстрации я использую eval здесь, чтобы позволить Python сделать это для меня.

s  = '''eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||c;k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('5 11=17;5 12=["/3/2/1/0/13.4","/3/2/1/0/15.4","/3/2/1/0/14.4","/3/2/1/0/7.4","/3/2/1/0/6.4","/3/2/1/0/8.4","/3/2/1/0/10.4","/3/2/1/0/9.4","/3/2/1/0/23.4","/3/2/1/0/22.4","/3/2/1/0/24.4","/3/2/1/0/26.4","/3/2/1/0/25.4","/3/2/1/0/18.4","/3/2/1/0/16.4","/3/2/1/0/19.4","/3/2/1/0/21.4"];5 20=0;',10,27,'40769|54|Images|Files|png|var|imanhua_005_140430179|imanhua_004_140430179|imanhua_006_140430226|imanhua_008_140430242|imanhua_007_140430226|len|pic|imanhua_001_140429664|imanhua_003_140430117|imanhua_002_140430070|imanhua_015_140430414||imanhua_014_140430382|imanhua_016_140430414|sid|imanhua_017_140430429|imanhua_010_140430289|imanhua_009_140430242|imanhua_011_140430367|imanhua_013_140430382|imanhua_012_140430367'.split('|'),0,{}))'''
js = eval('unpack' + s[s.find('}(')+1:-1])

Результат:

'var len=17;var pic=["/Files/Images/54/40769/imanhua_001_140429664.png","/Files/Images/54/40769/imanhua_002_140430070.png","/Files/Images/54/40769/imanhua_003_140430117.png","/Files/Images/54/40769/imanhua_004_140430179.png","/Files/Images/54/40769/imanhua_005_140430179.png","/Files/Images/54/40769/imanhua_006_140430226.png","/Files/Images/54/40769/imanhua_007_140430226.png","/Files/Images/54/40769/imanhua_008_140430242.png","/Files/Images/54/40769/imanhua_009_140430242.png","/Files/Images/54/40769/imanhua_010_140430289.png","/Files/Images/54/40769/imanhua_011_140430367.png","/Files/Images/54/40769/imanhua_012_140430367.png","/Files/Images/54/40769/imanhua_013_140430382.png","/Files/Images/54/40769/imanhua_014_140430382.png","/Files/Images/54/40769/imanhua_015_140430414.png","/Files/Images/54/40769/imanhua_016_140430414.png","/Files/Images/54/40769/imanhua_017_140430429.png"];var sid=40769;'

Дополнительное примечание : мне стало известно, что если основание> 36, то функция Alex 'int2base нарушается. Решение состоит в том, чтобы изменить его, добавив символы верхнего регистра, например, так: digs = string.digits + string.lowercase + string.uppercase

1 голос
/ 02 мая 2010

Кажется, это подходит для моих нужд: http://code.google.com/p/python-spidermonkey/

0 голосов
/ 15 июня 2017

при импорте модуля javacript не вариант, я использую этот

import re

def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

def unpack(p, a, c, k, e=None, d=None):
    while (c):
        c-=1
        if (k[c]):
            p = re.sub("\\b" + baseN(c, a) + "\\b",  k[c], p)
    return p

encrypted = r'''eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||c;k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('5 11=17;5 12=["/3/2/1/0/13.4","/3/2/1/0/15.4","/3/2/1/0/14.4","/3/2/1/0/7.4","/3/2/1/0/6.4","/3/2/1/0/8.4","/3/2/1/0/10.4","/3/2/1/0/9.4","/3/2/1/0/23.4","/3/2/1/0/22.4","/3/2/1/0/24.4","/3/2/1/0/26.4","/3/2/1/0/25.4","/3/2/1/0/18.4","/3/2/1/0/16.4","/3/2/1/0/19.4","/3/2/1/0/21.4"];5 20=0;',10,27,'40769|54|Images|Files|png|var|imanhua_005_140430179|imanhua_004_140430179|imanhua_006_140430226|imanhua_008_140430242|imanhua_007_140430226|len|pic|imanhua_001_140429664|imanhua_003_140430117|imanhua_002_140430070|imanhua_015_140430414||imanhua_014_140430382|imanhua_016_140430414|sid|imanhua_017_140430429|imanhua_010_140430289|imanhua_009_140430242|imanhua_011_140430367|imanhua_013_140430382|imanhua_012_140430367'.split('|'),0,{}))'''

encrypted = encrypted.split('}(')[1][:-1]

print eval('unpack(' + encrypted)

выход:

var len=17;var pic=["/Files/Images/54/40769/imanhua_001_140429664.png","/Files/Images/54/40769/imanhua_002_140430070.png","/Files/Images/54/40769/imanhua_003_140430117.png","/Files/Images/54/40769/imanhua_004_140430179.png","/Files/Images/54/40769/imanhua_005_140430179.png","/Files/Images/54/40769/imanhua_006_140430226.png","/Files/Images/54/40769/imanhua_007_140430226.png","/Files/Images/54/40769/imanhua_008_140430242.png","/Files/Images/54/40769/imanhua_009_140430242.png","/Files/Images/54/40769/imanhua_010_140430289.png","/Files/Images/54/40769/imanhua_011_140430367.png","/Files/Images/54/40769/imanhua_012_140430367.png","/Files/Images/54/40769/imanhua_013_140430382.png","/Files/Images/54/40769/imanhua_014_140430382.png","/Files/Images/54/40769/imanhua_015_140430414.png","/Files/Images/54/40769/imanhua_016_140430414.png","/Files/Images/54/40769/imanhua_017_140430429.png"];var sid=40769;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...