我在各种目录中都有一些HTML文件,它们都有类似的结构:
<html>
<head>...</head>
<body>
<nav>...</nav>
<section>...</section>
</body>
</html>
我想以编程方式将HTML部分替换为其他部分(例如,将<nav>
块替换为另一个nav
块[在我选择的文件中指定])我指定的文件。
我认为理想的解决方案是在Python中使用lxml
或类似的东西的某种工具,但是如果有一种简单的方法可以使用* nixy工具或现有程序来执行此操作,我我很乐意这样做,而不是整理剧本。
答案 0 :(得分:2)
您可以像这样使用BeautifulSoup for Python。
import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(htmldata)
nav = soup.find("nav")
nav.name = "new name"
例如:
import BeautifulSoup
html_data = "<nav>Some text</nav>"
soup = BeautifulSoup.BeautifulSoup(html_data)
nav = soup.find("nav")
nav.name = "nav2"
将更改:<nav></nav>
更改为<nav2></nav2>
答案 1 :(得分:1)
不要使用正则表达式或字符串解析。那些只会让你头疼。使用解析器。
在Ruby中我会使用Nokogiri:
require 'nokogiri'
html = '
<html>
<body>
<nav>...</nav>
<section>...</section>
</body>
</html>
'
doc = Nokogiri::HTML(html)
nav = doc.at('nav').content = "this is a new block"
puts doc.to_html
哪个输出:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<nav>this is a new block</nav><section>...</section>
</body></html>
当然,您希望将"this is a new block"
替换为File.read('snippet.html')
。
如果您的替换文件包含HTML代码段而不是nav
内容,请改为使用此代码:
nav = doc.at('nav').replace('<nav>this is a new block</nav>')
输出结果相同。 (并且再次使用File.read
从文件中获取该文件,如果这是你的倾向。)
在Nokogiri中,at
找到由CSS或XPath访问器指定的标记的第一个实例,并返回Node。我上面使用过CSS,但//nav
也可以使用。 at
猜测访问者的类型。如果您想要具体,可以使用at_css
或at_xpath
,因为可能有不明确的访问者。此外,Nokogiri有search
,它返回一个NodeSet,它就像一个数组。您可以根据需要迭代结果。而且,与at
一样,CSS和XPath特定版本分别为css
和xpath
。
Nokogiri有一个CLI界面,对于像这个例子这样简单的东西它可以工作,但我也可以用sed或Ruby / Perl / Python单行程来完成。
curl -s http://nokogiri.org | nokogiri -e'p $_.css("h1").length'
HTML很少这么简单,尤其是漫游狂野的任何东西,CLI或单线解决方案将迅速失控,或者只是死亡。我说这是基于多年编写许多蜘蛛和RSS聚合器 - 当你引入一个额外的HTML或XML源时,简单的开始会变得更复杂,而且它永远不会变得容易。使用解析器教会我先找他们。
答案 2 :(得分:1)
我最终编写了自己的小命令行工具来完成我想要的工作。它对我的用例非常有效,我打算随着时间的推移对其进行改进。它在GitHub上:trufflepig。
我希望它对其他人也有用。