我怎样才能不受捕获库的干扰捕获 HTML?
How can I capture HTML, unmolested by the capturing library?
是否有 Python 库可以让我获得任意 HTML 片段 而不会 干扰标记?据我所知,lxml、BeautifulSoup 和 pyquery 都使 soup.find(".arbitrary-class")
之类的东西变得容易,但是 HTML 和 returns 是格式化的。我想要原始的原始标记。
例如,假设我有这个:
<html>
<head>
<title>test</title>
</head>
<body>
<div class="arbitrary-class">
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
</div>
</body>
</html>
我想完全:
"
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
"
...空格和所有,并且没有修改标签以正确格式化(例如 <br />
)。
麻烦的是,似乎所有 3 个库似乎都在内部构建 DOM,并且只是 return 一个 Python 对象,表示文件 应该 而不是 是 ,所以我不知道 where/how 获取我需要的原始代码片段。
此代码:
from bs4 import BeautifulSoup
with open("index.html") as fp:
soup = BeautifulSoup(fp, "html.parser")
print soup.select(".arbitrary-class")[0].contents
将 return 你列在列表中:
[u'\n This is some', <br/>, u'\n markup with ', <br/>, u'\n', <p>some potentially problematic</p>, u'\n stuff in it ', <input name="w00t" type="text"/>, u'\n']
编辑:
正如丹尼尔在评论中指出的那样,这会导致标准化标签。
我能找到的唯一替代方法是使用解析器生成器,例如 pyparsing。下面的代码是对 withAttribute
函数的一些 example code 的轻微修改。
from pyparsing import *
html = """<html>
<head>
<title>test</title>
</head>
<body>
<div class="arbitrary-class">
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
</div>
</body>
</html>"""
div,div_end = makeHTMLTags("div")
# only match div tag having a class attribute with value "arbitrary-class"
div_grid = div().setParseAction(withClass("arbitrary-class"))
grid_expr = div_grid + SkipTo(div | div_end)("body")
for grid_header in grid_expr.searchString(html):
print repr(grid_header.body)
这段代码的输出如下:
'\n This is some<br />\n markup with <br>\n <p>some potentially problematic</p>\n stuff in it <input type="text" name="w00t">'
请注意,第一个 <br/>
现在有一个 space,并且 <input>
标签不再在结束 > 之前添加 /。与您的规范的唯一区别是尾随的白色 space 丢失了。您或许可以通过改进此解决方案来解决此差异。
是否有 Python 库可以让我获得任意 HTML 片段 而不会 干扰标记?据我所知,lxml、BeautifulSoup 和 pyquery 都使 soup.find(".arbitrary-class")
之类的东西变得容易,但是 HTML 和 returns 是格式化的。我想要原始的原始标记。
例如,假设我有这个:
<html>
<head>
<title>test</title>
</head>
<body>
<div class="arbitrary-class">
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
</div>
</body>
</html>
我想完全:
"
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
"
...空格和所有,并且没有修改标签以正确格式化(例如 <br />
)。
麻烦的是,似乎所有 3 个库似乎都在内部构建 DOM,并且只是 return 一个 Python 对象,表示文件 应该 而不是 是 ,所以我不知道 where/how 获取我需要的原始代码片段。
此代码:
from bs4 import BeautifulSoup
with open("index.html") as fp:
soup = BeautifulSoup(fp, "html.parser")
print soup.select(".arbitrary-class")[0].contents
将 return 你列在列表中:
[u'\n This is some', <br/>, u'\n markup with ', <br/>, u'\n', <p>some potentially problematic</p>, u'\n stuff in it ', <input name="w00t" type="text"/>, u'\n']
编辑:
正如丹尼尔在评论中指出的那样,这会导致标准化标签。
我能找到的唯一替代方法是使用解析器生成器,例如 pyparsing。下面的代码是对 withAttribute
函数的一些 example code 的轻微修改。
from pyparsing import *
html = """<html>
<head>
<title>test</title>
</head>
<body>
<div class="arbitrary-class">
This is some<br />
markup with <br>
<p>some potentially problematic</p>
stuff in it <input type="text" name="w00t">
</div>
</body>
</html>"""
div,div_end = makeHTMLTags("div")
# only match div tag having a class attribute with value "arbitrary-class"
div_grid = div().setParseAction(withClass("arbitrary-class"))
grid_expr = div_grid + SkipTo(div | div_end)("body")
for grid_header in grid_expr.searchString(html):
print repr(grid_header.body)
这段代码的输出如下:
'\n This is some<br />\n markup with <br>\n <p>some potentially problematic</p>\n stuff in it <input type="text" name="w00t">'
请注意,第一个 <br/>
现在有一个 space,并且 <input>
标签不再在结束 > 之前添加 /。与您的规范的唯一区别是尾随的白色 space 丢失了。您或许可以通过改进此解决方案来解决此差异。