我有以下 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">
//<![CDATA[
function CreateFixedHeaders() {}//]]>
</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 更熟悉),而且我知道这是达到我想要的结果的最快方法,至少对我来说是这样。
所以我需要帮助来违背我的本性而不是作恶。我想变坏并使用正则表达式,所以请有人给我指路明灯,引导我到非正则表达式的乐土。
谢谢
更新:
看来我不太清楚我的问题到底是什么,对此我深表歉意。我的问题是如何在没有正则表达式的情况下使用纯 Python 解析 HTML?
<script(.*)</script>
至于上面的代码示例,是错误的。我知道这是错误的,我用它作为起点的例子。
我希望这能澄清我的问题
更新 2
我只是想添加一些关于我正在做的事情的注释。
我正在抓取网站以获取我需要的数据。
一旦我们有了包含我们需要的数据的页面,它就会被保存到数据库中。
然后保存的网页显示给用户。
我要解决的问题就发生在这里。当您尝试与强制用户单击确认框的页面交互时,应用程序会抛出脚本错误。该应用程序不是网络浏览器,而是使用 Windows 中的网络浏览器 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 的回答是正确的。
最佳答案
至于去掉所有以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>
您的正则表达式的问题是该点 (.
) 与换行符不匹配。使用补集将匹配每个可能的字符。并确保在 [\s\S]+?
中使用 ?
以便它是惰性的而不是贪婪的。
关于python - 从 HTML 中删除 Script 标签和 on 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25121165/