如何将JavaScript插入到<script/>元素中?

3

我所拥有的是:

from lxml import etree
myscript = "if(0 < 1){alert(\"Hello World!\");}"
html = etree.fromstring("<script></script>")

for element in html.findall('//script'):
    element.text = myscript

result = etree.tostring(html)

我得到的是:

>>> result
'<script>if(0 &lt; 1){alert("Hello World!");}</script>'

我想要的是未转义的JavaScript代码:

>>> result
'<script>if(0 < 1){alert("Hello World!");}</script>'
2个回答

1
你做不到。lxml.etree和ElementTree是XML解析器,因此您想要解析或创建的任何内容都必须是有效的XML。而在某些节点文本中未转义的<不是有效的XML。它是有效的HTML但不是有效的XML。
这就是为什么在XHTML中,通常需要在<script>标签中添加CDATA块,这样您就可以放置任何内容,而无需担心有效的XML结构。
但在您的情况下,您只想生成HTML,为此,您应该使用HTML解析器。例如BeautifulSoup
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('<script></script>')
>>> soup.find('script').string = 'if(0 < 1){alert("Hello World!");}'
>>> str(soup)
'<script>if(0 < 1){alert("Hello World!");}</script>'

不是要无礼,但我认为从技术上讲,您可以使用lxml来解析<script>元素,问题在于OP使用的方法是错误的--试图更改文本而不是元素本身。 - Anzel
@Anzel,在你的回答中你自己使用了一个HTML解析器... 你可以很容易地确认,使用XML解析器无法处理所需的输出文本,只需尝试解析输出文本即可。 - poke
OP从未提到不使用HTML解析器。主要问题是如何将JS插入元素中。简单来说,通过替换元素本身可以实现。因为通常在XML文件中不会收到脚本标记,所以OP使用etree也是不合适的。 - Anzel
@Anzel,请阅读我的回答?它基本上是说“你不能使用XML解析器,要使用HTML解析器”,所以我真的不明白你想告诉我什么。 - poke
我有点困惑,lxml 不仅是一个 XML 解析器,它也是一个 HTML 解析器。BeautifulSoup 也可以使用 "lxml" 作为其解析器。 - Anzel

1
你的方法失败的原因是因为你试图更改元素的“文本”内容,而你需要更改/插入/附加其自身的元素,请参考以下示例:
In [1]: from lxml import html

In [2]: myscript = "<script>if(0 < 1){alert(\"Hello World!\");}</script>"

In [3]: template = html.fromstring("<script></script>")

# just a quick hack to get the <script> element without <html> <head>
In [4]: script_element = html.fromstring(myscript).xpath("//script")[0]

# insert new element then remove the old one
In [10]: for element in template.xpath("//script"):
   ....:     element.getparent().insert(0, script_element)
   ....:     element.getparent().remove(element)
   ....:

In [11]: print html.tostring(template)
<html><head><script>if(0 < 1){alert("Hello World!");}</script></head></html>

所以,是的,你仍然可以使用lxml插入元素。 我建议使用而不是,因为更加友好,涉及到html元素。

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