【问题标题】:Parsing Javascript with Python用 Python 解析 Javascript
【发布时间】:2016-12-01 16:27:24
【问题描述】:

在我的一个脚本中,我使用 urllib2BeautifulSoup 来解析 HTML 页面并读取 <script> 标记。

这就是我得到的:

<script>
var x_data = {
    logged: logged,
    lengthcarrousel: 2,
    products : [
        {
            "serial" : "106541823"
            ...
</script>

我的目标是读取 x_data 变量中的 JSON,但我不知道如何正确执行。 我想:

  • 转换为字符串并将第一个字符删除到 { 和最后一个相同的 }
  • 将正则表达式与“{.*}”之类的内容一起使用并获取第一组
  • 还有别的吗?

我不知道这些是否有效,是否还有其他方法可以很好地做到这一点。

您认为一种方法比另一种方法更可取吗?任何我可能不知道的方法?

提前感谢您的任何建议。

编辑:

根据建议,我得到了 Regexp 解决方案,但尽管使用了 re.MULTILINE ,但我无法在多行中搜索:

string1 = '<script>
var x_data = {
    logged: logged,
    lengthcarrousel: 2,
    products : [
        {
                "serial" : "106541823"}
]
}; 
</script>'


p = re.compile(r'\{.*\};',re.MULTILINE);
m = p.search(string1)
if m:
    print m.group(0)
else:
    print "Error !"

我总是收到“错误!”。

EDIT2:

适用于re.DOTALL

【问题讨论】:

  • 取决于输入的变化方式。如果它总是var x_data = ...,你可以用正则表达式替换掉锚定到字符串开头的那个位。您的解决方案可能介于简单到嵌入 JS 解析器一样复杂。
  • 您好,它永远是var x_data = ...。谢谢,我现在正在编写正则表达式解决方案。
  • @JohnMath 您不应该使用多行匹配。只需做一个锚定到字符串开头的匹配,你不需要在字符串中到处搜索。

标签: regex parsing beautifulsoup


【解决方案1】:

我认为这些方法在优雅和性能方面基本相同(使用{.*} 可能会稍微好一点,因为.* 是贪婪的,即几乎不会有回溯,因为在我看来它更“宽容” " 用于不同的 JS 代码格式细微差别)。你可能更感兴趣的是这个:https://docs.python.org/3.6/library/json.html

【讨论】:

    【解决方案2】:

    如果它总是看起来完全像这样,那么您可以根据看起来完全像这样来破解您提出的解决方案。

    因为程序员在代码中做所有事情,我怀疑在实践中它不会总是看起来完全一样,然后任何 hacky 解决方案都会很脆弱,并且会在意想不到的时候失败(读作“不可能不方便”)。 (众所周知,在解析代码时,正则表达式很笨拙)。

    如果您想正确执行此操作,您将需要获取一个真正的 JavaScript 解析器,将其应用于由脚本标记内容定义的代码片段,以生成 AST,然后在 AST 中搜索发生在的 JavaScript 嵌套结构看起来像 JSON,并获取该树的内容,漂亮打印。

    面对使用 JavaScript 赋值语句组装 JSON 片段的程序员,即使这样也很脆弱。您可以通过计算数据流并发现恰好组装 JSON 代码的代码集来处理此问题。这是相当多的工作。

    所以你可以决定你的解决方案的限制是什么,然后在你无法控制的人随意做某事时接受后果。

    【讨论】:

    • 哇。投反对票。投反对票的人,你愿意解释你投反对票的原因吗,特别是为什么这个答案不正确?
    • 我没有投反对票,但假设如果“它永远是var x_data = ....”(stackoverflow.com/questions/40915646/…)那么代码结构应该是相当固定的。
    • 这是 OP 在他可以做到的范围内断言和执行的。如果他真的可以执行此操作,那么他可以安全地入侵。我认为这是一个非常糟糕的赌注。我的经验是有人告诉我他们所有的代码都是按照特定的风格编写的原来是假的。我在这里有很多经验。
    • 当然你有,我记得你的名字,因为 StackOverflow 上有一些很好的答案,但毕竟人们应该假设一些事情。否则:例如,如果x_data 内容是通过网络获取的呢?尽管有问题标题,但我认为解析并非完全如此。
    • 其实,如果你不假设什么,这个问题一般是不可能的;图灵告诉我们,从代码中提取大多数事实等同于停机问题。诀窍是尽可能少地假设。如果你验证你的假设是正确的,或者经常是正确的,这样异常是可控的,那就更好了。 (我记得与 IBM 签订了一份源代码合同,经理在公司法令下发誓是 C 代码,我们计划为此使用 C 解析器;一百万行出现了,其中一半是 C++。拥有 GCC 的程序员不要不要在乎公司法令)。
    猜你喜欢
    • 1970-01-01
    • 2017-05-02
    • 2021-01-31
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    相关资源
    最近更新 更多