【问题标题】:how to remove text between <script> and </script> using python?如何使用 python 删除 <script> 和 </script> 之间的文本?
【发布时间】:2009-06-08 11:30:28
【问题描述】:

如何使用python删除&lt;script&gt;&lt;/script&gt;之间的文本?

【问题讨论】:

    标签: javascript python


    【解决方案1】:

    您可以将BeautifulSoup 与此(和其他)方法一起使用:

    soup = BeautifulSoup(source.lower())
    to_extract = soup.findAll('script')
    for item in to_extract:
        item.extract()
    

    这实际上从 HTML 中删除了节点。如果您想保留空的 &lt;script&gt;&lt;/script&gt; 标记,则必须使用 item 属性,而不仅仅是从汤中提取它。

    【讨论】:

    • 这是正确的答案。 Niloy 或任何阅读此问题的人,请忽略在这种情况下提倡使用正则表达式的任何答案,因为它们都有严重、容易被利用的安全问题。
    • 我同意@DrJokepu。不要尝试用正则表达式解析 HTML!
    • 我无法让它工作,因为脚本标签之间的文本包含如下内容: var str="
    • 这已经两年了,但我会尝试发表评论。 @DrJokepu 这将是一个好主意,但我无法将 html 加载到 BeautifulSoup 中,因为 javascript 中有错误的 html 标签,会在解析器中引发错误。我需要先使用 RegEx 剥离 javascript。
    • 从 bs4 导入 BeautifulSoup
    【解决方案2】:

    你想阻止XSS吗?仅仅消除&lt;script&gt; 标签并不能解决所有可能的攻击!以下是您可能易受攻击的多种方式(其中一些非常有创意)的清单http://ha.ckers.org/xss.html。阅读此页面后,您应该了解为什么仅使用正则表达式消除 &lt;script&gt; 标记不够健壮。 python 库lxml 有一个功能可以强大地清理您的 HTML 以使其安全显示。

    如果你确定你只是想消除&lt;script&gt;标签,这个lxml中的代码应该可以工作:

    from lxml.html import parse
    
    root = parse(filename_or_url).getroot()
    for element in root.iter("script"):
        element.drop_tree()
    

    注意:我使用正则表达式对所有解决方案投了反对票。在这里查看为什么不应该使用正则表达式解析 HTML:Using regular expressions to parse HTML: why not?

    注意 2: 另一个显示无法用正则表达式解析的 HTML 的 SO 问题:Can you provide some examples of why it is hard to parse XML and HTML with a regex?

    【讨论】:

      【解决方案3】:

      根据Pev和wr发布的答案,为什么不升级正则表达式,例如:

      pattern = r"(?is)<script[^>]*>(.*?)</script>"
      text = """<script>foo bar  
      baz bar foo  </script>"""
      re.sub(pattern, '', text)
      

      (?is) - 添加以忽略大小写并允许文本中的新行。这个版本还应该支持带有属性的脚本标签。

      编辑:我还不能添加任何 cmets,所以我只是在编辑我的答案。我完全同意下面的评论,正则表达式对于此类任务是完全错误的,并且 b。汤 ot lxml 好多了。但是提出的问题只是一个简单的例子,而正则表达式应该足以完成这样简单的任务。使用 Beautiful Soup 进行简单的文本删除可能太多了(过载?我不知道如何表达我的意思,请原谅我的英语)。

      顺便说一句,我犯了一个错误,代码应该是这样的:

      pattern = r"(?is)(<script[^>]*>)(.*?)(</script>)"
      text = """<script>foo bar  
      baz bar foo  </script>"""
      re.sub(pattern, '\1\3', text)
      

      【讨论】:

      • 怎么样?
      【解决方案4】:

      如果您要删除 &lt;script&gt;&lt;/script&gt; 之间的所有内容,为什么不直接删除整个节点?

      你期待一个 resign 风格的 src 和 body 吗?

      【讨论】:

        【解决方案5】:

        您可以使用HTMLParser 模块(复杂)或使用正则表达式来做到这一点:

        import re
        content = "asdf <script> bla </script> end"
        x=re.search("<script>.*?</script>", content, re.DOTALL)
        span = x.span() # gives (5, 27)
        
        stripped_content = content[:span[0]] + content[span[1]:]
        

        编辑:re.DOTALL,感谢 tgray

        【讨论】:

        • 这有很多潜在的问题,比如大小写、脚本标签是否有属性、可能转义的文本片段等。很难可靠地涵盖所有选项,使其更容易使用现有的,经过测试的库,例如 Beautiful Soup。
        • 您可能希望将 re.DOTALL / re.S 标志添加到您的搜索中,以便“点”字符与换行符匹配。没有这个,您将无法匹配跨越多行(其中大部分)的脚本块。
        • 不幸的是,一个合法的答案被否决了;这确实符合必要的规格。不是吗
        • @becomingGuru 请参阅我的解决方案中的两个链接,了解为什么使用正则表达式解析 HTML 是一个坏主意。虽然此分析器可能符合问题的“规范”,但它存在严重的安全问题,并不是真正可靠的解决方案。请参阅“mavnn”的注释和
        • (点击提交太快)并且“DrJokepu”也指出了同样的问题。
        【解决方案6】:

        如果您不想导入任何模块:

        string = "<script> this is some js. begone! </script>"
        
        string = string.split(' ')
        
        for i, s in enumerate(string):
            if s == '<script>' or s == '</script>' :
                del string[i]
        
        print ' '.join(string)
        

        【讨论】:

        • 再次, lol ';等等?
        • 嗯,他确实说过“”。
        【解决方案7】:

        Element Tree 是执行此操作的最简单和最甜蜜的软件包。是的,还有其他方法可以做到这一点;但不要使用任何'因为他们很烂! (通过马克朝圣者)

        【讨论】:

          【解决方案8】:

          我对 Python 的了解还不够好,无法告诉您解决方案。但是如果你想用它来清理用户输入,你必须非常非常小心。删除和之间的东西并不能捕获所有内容。也许你可以看看现有的解决方案(我假设 Django 包含类似的东西)。

          【讨论】:

            【解决方案9】:
            example_text = "This is some text <script> blah blah blah </script> this is some more text."
            
            import re
            myre = re.compile("(^.*)<script>(.*)</script>(.*$)")
            result = myre.match(example_text)
            result.groups()
              <52> ('This is some text ', ' blah blah blah ', ' this is some more text.')
            
            # Text between <script> .. </script>
            result.group(2)
              <56> 'blah blah blah'
            
            # Text outside of <script> .. </script>
            result.group(1)+result.group(3)
              <57> 'This is some text  this is some more text.'
            

            【讨论】:

            • 请注意,
            • myre = re.compile("(^.*)(.*)(.*$)") 来捕捉它。
            猜你喜欢
            • 2015-12-26
            • 1970-01-01
            • 2018-01-27
            • 1970-01-01
            • 2022-12-05
            • 1970-01-01
            • 2018-12-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多