问题 使用Ruby代码解析Javascript


我正在Ruby中编写测试代码并尝试解析网站的HTML源文件。它有一个JavaScript变量,我可以用它来与其他值进行比较。例如:

<script type="text/javascript" language="JavaScript">
  function GetParam(name) {   
    var req_var = {
      a: 'xyz', 
      b: 'yy.com', 
      c: 'en', 
      d:0, 
      e: 'y'
     };
  }
</script>

在这里,我想提取变量 req_var 从这个功能。有可能吗?如果是这样,请有人帮助我吗?


4029
2018-02-09 00:29


起源

你使用了Nokogiri标签,所以我不确定你的意思是“提取变量 req_var 从这个函数“。你需要帮助使用Nokogiri才能找到这个脚本块吗?你想从HTML中得到什么,只是命名变量的文本 req_var?你想将它转换成Ruby Hash吗? - Phrogz
我在相同的代码中使用Nokogiri进行其他html解析。所以,理想情况下,如果我可以使用Nokogiri,它会很棒。如果我可以将它转换为ruby哈希,它会很棒。 - rubytester


答案:


ruby中的javascript解析器


8
2018-02-09 00:35



其中,rkelly是最近更新的。 - Clay Bridges


您可以使用正则表达式来解析它,如下所示:

k =“function GetParam(name){var req_var = {a:'xyz',b:'yy.com',c:'en',d:0,e:'y'};}”
变量= k.match(/ var \ s + req_var \ s + = \ s +(。*?); / m)[1]
p变量

=>“{a:'xyz',b:'yy.com',c:'en',d:0,e:'y'}”

4
2018-02-09 00:37



这可能适用于JavaScript的一些非常有限的部分,但通常不可能只使用正则表达式解析类似JavaScript代码(或任何编程语言)的内容。 (当然,你可能知道@Pan Thomakos,但是我正在输入这个评论,以便年轻,易受影响的人可以在未来几年阅读答案。) - Pointy
这是真的,但这似乎是一个足够受限的情况,他不需要解析整个javascript程序,他只需要'var req_var ='和';'之间的值。 - Pan Thomakos
谢谢,这有帮助。 - rubytester


rkelly gem为我抛出一个例外,所以我使用了fork rkelly-混音  - 你必须卸载原来的,因为它们使用相同的名称:

宝石卸载rkelly
  gem install rkelly-remix

我有以下JS代码:

  var xpos = 0;
  var ypos = 0;
  var city = 'Parish';
  var cashSaldo = '0.00';
  var bankSaldo = '';
  var address = 'Lot: 0 - 0';
  var simplemode = true;
  var email_reminder = true;
  var text_citylist = 'Take a cab to';
  var text_nostreet = 'Lot';
  var text_lotpos = 'Lot:';
  var text_products_title = 'Products';
  var text_products_subtitle = 'Produce and set prices';
  var text_title = 'Miniconomy';
  var text_has_harbor = 'This city has a harbor';
  var products = {"gron":{"ln":"Clay"},"stee":{"ln":"Brick"},"ijee":{"ln":"Iron Ore"},"boom":{"ln":"Tree"},"goud":{"ln":"Gold"},"olie":{"ln":"Oil"},"oven":{"ln":"Oven"},"ijze":{"ln":"Iron"},"hout":{"ln":"Wood"},"schi":{"ln":"Bulletproof Vest"},"benz":{"ln":"Gas"},"pomp":{"ln":"Pump"},"schr":{"ln":"Screwdriver"},"sche":{"ln":"Shovel"},"moto":{"ln":"Electrical Engine"},"plas":{"ln":"Plastic"},"zaag":{"ln":"Saw"},"mach":{"ln":"Machine"},"chip":{"ln":"Chip"},"tele":{"ln":"Telephone"},"came":{"ln":"Camera"},"alar":{"ln":"Alarm"},"glas":{"ln":"Glass"}};
  var isChristmas = 0;
  var newMap = 1;

这是我必须编写的代码来解析它:

o = lambda do |x|
  next true if x == [:true]
  next x.size != 2 ? fail : eval(x[1].to_s) if x[0] == :lit || x[0] == :str
  next x.size != 2 ? fail : Hash[ x[1].map do |a,b,c|
    fail unless a == :property
    fail unless b.is_a? Symbol
    [eval(b.to_s).to_sym, o[c]]
  end ] if x.first == :object
  fail x.inspect
end

require "rkelly"

result = Hash[ RKelly::Parser.new.parse(my_js_code).to_sexp.map do |k, v|
  fail unless k == :var
  fail unless v.size == 1
  a, b, c = v.first
  fail unless a == :var_decl
  k, v = c
  fail unless k == :assign
  [b, o[v]]
end ]

这导致:

{:xpos=>0,
 :ypos=>0,
 :city=>"Parish",
 :cashSaldo=>"0.00",
 :bankSaldo=>"",
 :address=>"Lot: 0 - 0",
 :simplemode=>true,
 :email_reminder=>true,
 :text_citylist=>"Take a cab to",
 :text_nostreet=>"Lot",
 :text_lotpos=>"Lot:",
 :text_products_title=>"Products",
 :text_products_subtitle=>"Produce and set prices",
 :text_title=>"Miniconomy",
 :text_has_harbor=>"This city has a harbor",
 :products=>
  {:gron=>{:ln=>"Clay"},
   :stee=>{:ln=>"Brick"},
   :ijee=>{:ln=>"Iron Ore"},
   :boom=>{:ln=>"Tree"},
   :goud=>{:ln=>"Gold"},
   :olie=>{:ln=>"Oil"},
   :oven=>{:ln=>"Oven"},
   :ijze=>{:ln=>"Iron"},
   :hout=>{:ln=>"Wood"},
   :schi=>{:ln=>"Bulletproof Vest"},
   :benz=>{:ln=>"Gas"},
   :pomp=>{:ln=>"Pump"},
   :schr=>{:ln=>"Screwdriver"},
   :sche=>{:ln=>"Shovel"},
   :moto=>{:ln=>"Electrical Engine"},
   :plas=>{:ln=>"Plastic"},
   :zaag=>{:ln=>"Saw"},
   :mach=>{:ln=>"Machine"},
   :chip=>{:ln=>"Chip"},
   :tele=>{:ln=>"Telephone"},
   :came=>{:ln=>"Camera"},
   :alar=>{:ln=>"Alarm"},
   :glas=>{:ln=>"Glass"}},
 :isChristmas=>0,
 :newMap=>1}

0
2017-09-04 04:47