用jsoup解析JavaScript

16

在一个 HTML 页面中,我想获取一个 JavaScript 变量的值。
以下是 HTML 页面的片段:

<input id="hidval" value="" type="hidden"> 
<form method="post" style="padding: 0px;margin: 0px;" name="profile" autocomplete="off">
<input name="pqRjnA" id="pqRjnA" value="" type="hidden">
<script type="text/javascript">
    key="pqRjnA";
</script>

我的目标是使用jsoup从此页面读取变量key的值。
使用jsoup是否可能?如果可以,那么怎么做呢?


1
你需要获取脚本内容,然后手动解析,或者看看是否可以使用Rhino从执行的JS片段中获取上下文。 - Dave Newton
@Reimeus:不是初始化的问题,可以在其他地方完成。这里是将某个值赋给变量“key”。 - ravi
添加了 kotlin 标签,因为一个类似的 Kotlin 问题被标记为重复,并与此问题链接。 - Mahozad
2个回答

35

由于jsoup不是一个javascript库,您有两种解决方案:

A. 使用javascript库

  • 优点:

    • 完整支持Javascript
  • 缺点:

    • 需要额外的库/依赖项

B. 使用Jsoup + 手动解析

  • 优点:

    • 无需额外的库
    • 足够简单任务
  • 缺点:

    • 不如javascript库灵活

这是一个使用jsoup和一些"manual"代码获取key的示例:

Document doc = ...
Element script = doc.select("script").first(); // Get the script part


Pattern p = Pattern.compile("(?is)key=\"(.+?)\""); // Regex for the value of the key
Matcher m = p.matcher(script.html()); // you have to use html here and NOT text! Text will drop the 'key' part


while( m.find() )
{
    System.out.println(m.group()); // the whole key ('key = value')
    System.out.println(m.group(1)); // value only
}

输出(使用您的HTML部分):

key="pqRjnA"
pqRjnA

嘿,Jsoup + 手动解析是这个问题的很好的解决方案,但是当我将js变量用作数组时会出现错误。例如:keyArray = [1, 2, 3],你能否给我提供解决方案? - Anil Kumar Pandey
你可以使用这个正则表达式:(?s)(keyArray)\\s??=\\s??\\[(.*?)\\]。如果定义了两个组:第一组是变量名,第二组是值(在 [ ] 中的值)。 - ollo
如果我在脚本标签中有类似于 abc.xyz.init({requiredJsonObjectAsAnArgument}); 的内容,并且我只想解析 requiredJsonObjectAsAnArgument,你能为我提供适用的正则表达式吗? - user79307
1
请尝试使用(?s)\\.init\\(\\{(.+?)\\}\\); - 第一组中包含requiredJsonObjectAsAnArgument作为必需的JSON对象参数。 - ollo

0

Kotlin问题被标记为重复,并指向了这个问题。
所以,这是我用Kotlin实现的方法:

val (key, value) = document
    .select("script")
    .map(Element::data)
    .first { "key" in it } // OR single { "key" in it }
    .split("=")
    .map(String::trim)
val pureValue = value.replace(Regex("""["';]"""), "")
println("$key::$pureValue") // key::pqRjnA

另一个版本:

val (key, value) = document
    .select("script")
    .first { Regex("""key\s*=\s*["'].*["'];""") in it.data() }
    .data()
    .split("=")
    .map { it.replace(Regex("""[\s"';]"""), "") }
println("$key::$value") // key::pqRjnA

脚注

要获取文档,您可以这样做:

从文件中:
val input = File("my-document.html")
val document = Jsoup.parse(input, "UTF-8")

从服务器中:
val document = Jsoup.connect("the/target/url")
    .userAgent("Mozilla")
    .get()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接