【发布时间】:2018-05-07 18:23:57
【问题描述】:
我有一个无序列表网页,我想将它们转换为 pandas 数据框,作为 NLP 工作流程的第一步。
import pandas as pd
from bs4 import BeautifulSoup
html = '''<html>
<body>
<ul>
<li>
Name
<ul>
<li>Many</li>
<li>Stories</li>
</ul>
</li>
</ul>
<ul>
<li>
More
</li>
</ul>
<ul>
<li>Stuff
<ul>
<li>About</li>
</ul>
</li>
</ul>
</body>
</html>'''
soup = BeautifulSoup(html, 'lxml')
目标是让每个顶级列表变成一个数据框,看起来像这样的输出:
0 1 2
0 Name Many Stories
1 More null null
2 Stuff About null
我尝试使用以下代码获取所有列表项(包含子列表)
target = soup.find_all('ul')
但它返回双输出:
[<li>
Name
<ul>
<li>Many</li>
<li>Stories</li>
</ul>
</li>, <li>Many</li>, <li>Stories</li>, <li>
More
</li>, <li>Stuff
<ul>
<li>About</li>
</ul>
</li>, <li>About</li>]
真的迷路了。谢谢。
【问题讨论】:
-
首先,您要查找页面上的所有
ul元素,因此因为“Many”和“Stories”包含在两个不同的ul元素下,您会看到它们两次.通过使用特定路径而不是一揽子搜索所有内容,可能会更好地指定您想要的ul元素 -
为了补充上面关于路径的观点,您似乎正在寻找出现在
body标记之后的ul元素,因此请定义该路径。重复的实例是由于body > ul > li > ul造成的,soup.find_all('ul')也是如此 -
我建议您查看here,以便您可以使用 XPaths 来帮助您解决此问题。您的 XPath 最终会是这样的:
body/ul。单斜杠表示任何ul元素,它是body元素的直接子元素 -
感谢@WStokvis,我可以使用 xpath 获取每个列表的顶层,但无法弄清楚如何迭代每个列表。我有成千上万的这些要排序,而且都是 1990 年代未标记的 html。
-
如果没有更多内容可供使用,我无法提供有关如何正确编码以便获得所需内容的见解。我想我首先要看的是您是否可以编写一些逻辑来搜索树中嵌套的
ul元素。例如,如果您看到<ul>跟随另一个<ul>而没有</ul>,那么显然这些元素将被嵌套,因此您需要区别对待它们。
标签: python pandas xpath nlp elementtree