将JS JSON解析为Ruby

Parsing JS JSON to Ruby

本文关键字:Ruby JS JSON      更新时间:2023-09-26

所以我正在做一个小项目,涉及到在论坛上抓取数据(而不是垃圾邮件)。

我对JSJSON数组有一个问题,我不知道如何使它在ruby中可读。

下面是我从论坛上得到的一个例子。

'n    //<!--'n            require(['"main'"], function() {'n            require(['"PoE/Item/DeferredItemRenderer'"], function(R) { (new R([[0,{'"verified'":false,'"w'":2,'"h'":3,'"icon'":'"http:''/''/webcdn.pathofexile.com''/image''/Art''/2DItems''/Armours''/BodyArmours''/BodyStrDexInt1C.png?scale=1&v=5a4eb9d863bef835aa3d9cc9224f51a51'",'"support'":true,'"league'":'"Hardcore'",'"sockets'":[{'"group'":0,'"attr'":'"S'"},{'"group'":0,'"attr'":'"I'"},{'"group'":0,'"attr'":'"S'"},{'"group'":0,'"attr'":'"I'"},{'"group'":1,'"attr'":'"D'"},{'"group'":2,'"attr'":'"I'"}],'"name'":'"Corruption Ward'",'"typeLine'":'"Vaal Regalia'",'"identified'":true,'"properties'":[{'"name'":'"Quality'",'"values'":[['"+20%'",1]],'"displayMode'":0},{'"name'":'"Energy Shield'",'"values'":[['"605'",1]],'"displayMode'":0}],'"requirements'":[{'"name'":'"Level'",'"values'":[['"68'",0]],'"displayMode'":0},{'"name'":'"Int'",'"values'":[['"194'",0]],'"displayMode'":1}],'"explicitMods'":['"+50 to Intelligence'",'"60% increased Energy Shield'",'"+140 to maximum Energy Shield'"],'"frameType'":2,'"socketedItems'":[]},[]],[1,{'"verified'":true,'"w'":2,'"h'":2,'"icon'":'"http:''/''/webcdn.pathofexile.com''/image''/Art''/2DItems''/Armours''/Helmets''/HelmetInt4.png?scale=1&v=0f230458eaf985d877912eae780a91fc1'",'"support'":true,'"league'":'"Hardcore'",'"sockets'":[{'"group'":0,'"attr'":'"D'"},{'"group'":0,'"attr'":'"S'"},{'"group'":1,'"attr'":'"I'"},{'"group'":1,'"attr'":'"I'"}],'"name'":'"Dusk Visage'",'"typeLine'":'"Royal Circlet'",'"identified'":true,'"properties'":[{'"name'":'"Quality'",'"values'":[['"+20%'",1]],'"displayMode'":0},{'"name'":'"Energy Shield'",'"values'":[['"261'",1]],'"displayMode'":0}],'"requirements'":[{'"name'":'"Level'",'"values'":[['"65'",0]],'"displayMode'":0},{'"name'":'"Int'",'"values'":[['"138'",0]],'"displayMode'":1}],'"explicitMods'":['"+22 to Intelligence'",'"43% increased Energy Shield'",'"+61 to maximum Energy Shield'",'"22% increased Rarity of Items found'",'"+20% to Fire Resistance'",'"14% increased Block and Stun Recovery'"],'"frameType'":2,'"socketedItems'":[]},[]],[2,{'"verified'":false,'"w'":2,'"h'":3,'"icon'":'"http:''/''/webcdn.pathofexile.com''/image''/Art''/2DItems''/Armours''/Shields''/ShieldStrInt5.png?scale=1&v=823818e9cfc86e3ea4c642b97695932c1'",'"support'":true,'"league'":'"Hardcore'",'"sockets'":[{'"group'":0,'"attr'":'"S'"},{'"group'":1,'"attr'":'"I'"},{'"group'":2,'"attr'":'"I'"}],'"name'":'"Cataclysm Rock'",'"typeLine'":'"Angelic Kite Shield'",'"identified'":true,'"properties'":[{'"name'":'"Quality'",'"values'":[['"+20%'",1]],'"displayMode'":0},{'"name'":'"Chance to Block'",'"values'":[['"24%'",0]],'"displayMode'":0},{'"name'":'"Armour'",'"values'":[['"322'",1]],'"displayMode'":0},{'"name'":'"Energy Shield'",'"values'":[['"324'",1]],'"displayMode'":0}],'"requirements'":[{'"name'":'"Level'",'"values'":[['"55'",0]],'"displayMode'":0},{'"name'":'"Str'",'"values'":[['"70'",0]],'"displayMode'":1},{'"name'":'"Int'",'"values'":[['"70'",0]],'"displayMode'":1}],'"implicitMods'":['"+24% to all Elemental Resistances'"],'"explicitMods'":['"108% increased Armour and Energy Shield'",'"+92 to maximum Energy Shield'",'"+37% to Cold Resistance'",'"+7% to Lightning Resistance'",'"12% increased Block and Stun Recovery'"],'"frameType'":2,'"socketedItems'":[]},[]],[3,{'"verified'":true,'"w'":2,'"h'":1,'"icon'":'"http:''/''/webcdn.pathofexile.com''/image''/Art''/2DItems''/Belts''/Belt1.png?scale=1&v=a40ff49a65beb9e722af0f85159432f11'",'"support'":true,'"league'":'"Hardcore'",'"sockets'":[],'"name'":'"Rage Snare'",'"typeLine'":'"Rustic Sash'",'"identified'":true,'"requirements'":[{'"name'":'"Level'",'"values'":[['"39'",0]],'"displayMode'":0}],'"implicitMods'":['"21% increased Physical Damage'"],'"explicitMods'":['"+19 to maximum Energy Shield'",'"+32% to Fire Resistance'",'"+15% to Cold Resistance'",'"+31% to Lightning Resistance'"],'"frameType'":2,'"socketedItems'":[]},[]],[4,{'"verified'":false,'"w'":2,'"h'":2,'"icon'":'"http:''/''/webcdn.pathofexile.com''/image''/Art''/2DItems''/Armours''/Gloves''/MaligarosVirtousity.png?scale=1&v=2614d1663cda7c88fa4b600c03cbc42a1'",'"support'":true,'"league'":'"Hardcore'",'"sockets'":[{'"group'":0,'"attr'":'"S'"},{'"group'":0,'"attr'":'"D'"},{'"group'":0,'"attr'":'"I'"},{'"group'":0,'"attr'":'"I'"}],'"name'":'"Maligaro's Virtuosity'",'"typeLine'":'"Deerskin Gloves'",'"identified'":true,'"properties'":[{'"name'":'"Quality'",'"values'":[['"+20%'",1]],'"displayMode'":0},{'"name'":'"Evasion Rating'",'"values'":[['"121'",1]],'"displayMode'":0}],'"requirements'":[{'"name'":'"Level'",'"values'":[['"21'",0]],'"displayMode'":0},{'"name'":'"Dex'",'"values'":[['"33'",0]],'"displayMode'":1}],'"explicitMods'":['"+23 to Dexterity'",'"5% increased Attack Speed'",'"50% increased Global Critical Strike Chance'",'"41% increased Global Critical Strike Multiplier'",'"63% increased Evasion Rating'"],'"flavourText'":['"Maligaro operated effortlessly,''r'",'"with great speed and terrible consequences.'"],'"frameType'":3,'"socketedItems'":[]},[]]])).run(); });'n        });    //-->'n"

字符串中几乎有有效的JSON代码,但其中的引号是转义的,它被封装在一些使用该JSON数据的JavaScript代码中。

如果去掉JavaScript代码并取消对引号的捕获,就可以解析JSON。你可以用几个正则表达式来实现这一点。

假设您的测试数据在一个名为download.txt的文件中,则此代码将执行以下操作:

#!/usr/bin/env ruby
require 'json'
input = File.read( 'download.txt' )
a = input.gsub( /['r'n]/m, '' )  # Remove newlines
b = a.gsub( /''"/, '"' )         # Unescape quotes
c = b.sub( /^.*'(new R'(/, '' )  # Remove JavaScript at beginning
d = c.sub( /')')'.run.*$/, '' )  # Remove JavaScript at end
j = JSON.parse( d )  # Now we have JSON we can parse
p j.class   # Prints Array
p j.length  # Prints 5
p j         # Prints JSON data