从HTML中删除脚本标记和属性

时间:2014-08-04 14:34:55

标签: python html regex parsing python-3.x

我有以下HTML,我需要删除HTML中的脚本标记和任何与脚本相关的属性。通过脚本相关属性,我的意思是任何以on开头的属性。

<body>
<script src="...">

    </script>
<div onresize="CreateFixedHeaders()" onscroll="CreateFixedHeaders()" id="oReportDiv" style="overflow:auto;WIDTH:100%">

<script type="text/javascript" language="javascript">

//&lt;![CDATA[

function CreateFixedHeaders() {}//]]&gt;
</script>
<script>

            var ClientReportfb64a4706a3749c484169e...
        </script>
</body>

我的第一个想法是使用BeautifulSoup删除标签和属性。不幸的是,我无法使用BeautifulSoup。看到BeautifulSoup不在桌面上,我可以看到两个选项。我看到的第一个选项是拆分字符串并根据索引进行解析。这对我来说似乎是一个糟糕的解决方案。

另一种选择是使用正则表达式。但是,我们知道这不是一个好的解决方案(Cthulhu Parsing)。

现在考虑到这一点,我个人认为使用正则表达式去除属性是可以的。毕竟,那些仍然是简单的字符串操作。

所以删除我拥有的属性:

script_attribute_regex = r'\son[a-zA-Z]+="[a-zA-Z0-0\.;\(\)_]+"'
result = re.sub(script_attribute_regex, "", page_source)

正如我之前所说,我个人认为以上完全可以接受使用正则表达式和HTML。但我仍想对上述用法有所了解。

然后是脚本标签的问题。我非常想接受正则表达式,因为我了解它们,而且我知道我需要的是非常简单的。类似的东西:

<script(.*)</script>

以上将开始让我接近我需要的东西。是的,我知道上面的RegEx将从第一个开始脚本标签开始抓取所有内容,直到最后一个结束脚本标签,但它是一个开始的例子。

我非常想使用正则表达式,因为我熟悉它们(比Python更多)我知道这是达到我想要的结果的最快方式,至少对我来说这是。

所以我需要帮助违背我的本性,而不是邪恶。我想成为邪恶的并使用RegEx,所以有人请告诉我光明并引导我到非正规表达的承诺之地。

由于

更新

看起来我对自己的问题实际上并不是很清楚,我为此道歉。我的问题是如何使用没有正则表达式的纯Python解析HTML?

<script(.*)</script>

至于上面的代码示例,它是错误的。我知道这是错的,我用它作为一个起点的例子。

我希望这能解决我的问题

更新2

我只是想补充一些关于我在做什么的笔记。

我正在抓取一个网站以获取我需要的数据。

一旦我们拥有包含我们需要的数据的页面,它就会保存到数据库中。

然后将保存的网页显示给用户。

我想解决的问题就在这里。当您尝试与强制用户单击确认框的页面进行交互时,应用程序将引发脚本错误。该应用程序不是Web浏览器,而是使用Windows中的Web浏览器DLL(我暂时忘记了该名称)。

有问题的错误只发生在这一个网站的这一页中。

更新3

添加更新后,我意识到我在思考问题,我正在寻找更通用的解决方案。但是,在这种情况下,并不是所需要的。

页面是动态生成的,但脚本标记将保持静态。考虑到这一点,解决方案变得更加简单。有了它,我不再需要像HTML那样对待它,而是将其视为静态字符串。

所以我正在寻找的解决方案是

import re


def strip_script_tags(page_source: str) -> str:
    pattern = re.compile(r'\s?on\w+="[^"]+"\s?')
    result = re.sub(pattern, "", page_source) 
    pattern2 = re.compile(r'<script[\s\S]+?/script>')
    result = re.sub(pattern2, "", result)
    return result

我想避免使用正则表达式,因为我仅限于使用标准库,正则表达式似乎是这种情况下的最佳解决方案。这意味着@ skamazin的回​​答是正确的。

1 个答案:

答案 0 :(得分:2)

至于删除以on开头的所有属性,您可以尝试this

它使用正则表达式:

\s?on\w+="[^"]+"\s?

用空字符串替换(删除)。所以在Python中它应该是:

pattern = re.compile(ur'\s?on\w+="[^"]+"\s?')
subst = u""
result = re.sub(pattern, subst, file) 

如果您尝试匹配脚本标记之间的任何内容,请尝试:

<script[\s\S]+?/script>

DEMO

正则表达式的问题在于该点(.)与换行符不匹配。使用补充集将匹配每个可能的字符。并确保使用?中的[\s\S]+?,以便它变得懒惰而不是贪婪。