java解析JavaScript片段

前几天帮某个人抓取某电商网站商品属性的,得到页面后需要解析一个<script>内的代码获得其中一个json对象的属性, 开始是想字符串截取呢,后来感觉不怎么好,就换成用java解析script了,感觉还行,其中有几个坑,在这里记录下,

对于一段js代码,java在解析时,需要补齐其中的空间变量,比如 var window={}; 
还有js中调用的函数,如果不关心的话,也需要按调用方式预先定义好,比如consloe.log();否则js片段缺少变量无法继续
对于你需要获取的数据,比如json串,最好还是写个js函数附在js片段后面来执行获取;
对于简单的工具函数也最好能抄过来定义好
每个变量,函数都需要以分号结尾,java这样的强类型遇到js这样的弱类型,错误提示简直不能看啊.(此处耗时1小时),因为 var a=function(){}; 这里最后缺少一个分号,提示各种错乱.
 

我需要解析的js如下:

1window.markPageStylesReady("e58dfbdc-9154-4482-aeb3-d1d32aa05195"); 2if (!window.pageParams) { 3 window.pageParams = {}; 4} 5window.pageParams["e58dfbdc-9154-4482-aeb3-d1d32aa05195"] = { 6 "browser_type": "unknown", 7 "contest": { 8 "product_rating": { 9 "rating": 5.0, 10 }, 11 "id": "5731b2460efe256073e4631e", 12 "remarket_tag": { 13 "name": "Hats" 14 }, 15 "commerce_product_info": { 16 "fbw_pending": 0, 17 "is_fulfill_by_wish": false, 18 "variations": [{ 19 "original_price": 1, 20 "shipping_price_country_code": "US", 21 "color": "Multicolor", 22 "variation_id": "573307b481e30f5ec28e3801", 23 "type": ["1"], 24 "size": [{ 25 "1": "1" 26 }], 27 "shipping": 1 28 }, { 29 "original_price": 1, 30 "color": "Multicolor", 31 "type": ["2"], 32 "size": [{ 33 "2": "2" 34 }], 35 "size_ordering": 0, 36 "variation_id": "123", 37 "shipping": 1 38 }], 39 "is_active_fbw_in_us": false, 40 }, 41 "contest_selected_picture": "0", 42 "num_bought": 0, 43 "is_expired": false, 44 "num_won": 0, 45 "external_url": "http:\/\/www.xxoo.com\/c\/5731b2460efe256073e4631e" 46 }, 47 "force_login_required": false 48}; 49// This parameter will get consumed by the page's script and used 50// to initialize the page correctly 51window.nextInitializePageId = 'e58dfbdc-9154-4482-aeb3-d1d32aa05195';

 需要获取
window.pageParams['e58dfbdc-9154-4482-aeb3-d1d32aa05195'].contest.commerce_product_info.variations
这个json串,
为此找了个json2str函数,稍微写了点垃圾代码

然后用javax.script.ScriptEngine就搞定了:

代码如下:

1///file是就整个html文件 2Document doc = Jsoup.parse(file, "UTF-8"); 3 Elements ee = doc.getElementsByTag("script"); 4 String text = ""; 5 for ( Element e : ee ) { 6 String t = e.html(); 7 if ( t.indexOf("\"5731b2460efe256073e4631e\"") > 0 && t.indexOf("\"product_id\"") > 0 ) { 8 text = t; 9 } 10 } 11 if ( "".equals(text) ) return null; 12// System.out.println(text); 13 String strbef = ";var t=''; var window={ markPageStylesReady: function(a){t=a} } ; "; 14 String straft = ";function getv(){return window.pageParams[t].contest.commerce_product_info.variations ;}"; 15 String json2str = "function json2str(o) { " 16 +" var arr = []; " 17 +" var fmt = function(s) { " 18 +" if( typeof s == \"string\") {return \"\\\"\" + s + \"\\\"\" ;}" 19 +" if( typeof s == \"number\") {return \"\\\"\" + s + \"\\\"\";} " 20 +" if (typeof s == \"object\" ) { if( s != null) { return json2str(s);} } " 21 +" return s ;" 22 +" }; " 23 +" for (var i in o) {arr.push(\"\\\"\" + i + \"\\\":\" + fmt(o[i]));} " 24 +" return \"{\" + arr.join(\",\") + \"}\"; " 25 +"}; " 26 + " var o=getv(); " 27 + " function aa(){ return json2str(o);}; " ; 28 29 /*所有变量和函数都要有分号结尾..*/ 30 31 javax.script.ScriptEngineManager sem = new javax.script.ScriptEngineManager(); 32 javax.script.ScriptEngine engine = sem.getEngineByExtension("js"); 33 engine.eval(strbef + text + straft+json2str); 34 Invocable inv = (Invocable) engine; 35 Object obj = inv.invokeFunction("aa"); 36 JSONObject jsonobj = JSON.parseObject(obj.toString()); 37 System.out.println(jsonobj.getJSONObject("0").get("max_shipping_time"));

    如期得到结果,good job!

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java日期时间API系列31

  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

java解析JavaScript片段 - HelloWorld