0

我正在使用 python + beautifulsoup 来解析 html。我的问题是我有可变数量的文本项。在这种情况下,例如,我想提取“文本 1”、“文本 2”、...“文本 4”。在其他网页中,可能只有“文本 1”或可能有两个,等等。所以它会改变。如果'Text x's 包含在标签中,它会让我的生活更轻松。但他们不是。我可以使用 next 和 previous(或者可能 nextSibling 和 previousSibling)访问它们,但是我不知道如何获得所有这些。这个想法是(假设我遇到的最大数字是四个)将“文本 1”写入文件,然后一直到“文本 4”。就是在这种情况下。在只有“文本 1”的情况下,我会将“文本 1”写入文件,然后只有 2-4 的空白。关于我应该做什么的任何建议?

<div id="DIVID" style="display: block; margin-left: 1em;">
  <b>Header 1</b>
  <br/>
  Text 1
  <br/>
  Text 2
  <br/>
  Text 3
  <br/>
  Text 4
 <br/>
 <b>Header 2</b>
</div>

当我在做的时候,我有一个不那么相关的问题。假设我有一个网站,该网站具有可变数量的链接,这些链接都链接到 html,就像我上面的内容一样。这不是这个应用程序,但想想 craigslist - 中央页面上有许多链接。我需要能够访问这些页面中的每一个才能进行解析。什么是这样做的好方法?

谢谢!

额外:下一个网页可能如下所示:

<div id="DIVID2" style="display: block; margin-left: 1em;">
  <b>Header 1</b>
  <br/>
  Different Text 1
  <br/>
  Different Text 2
 <br/>
 <b>Header 2</b>
</div>

注意区别:

  1. DIVID 现在是 DIVID2。我可以根据页面上的其他解析来找出 DIVID 的结尾。这不是问题。

  2. 我只有两项文本而不是四项。

  3. 现在的文字不同了。

注意关键的相似性:

  1. 标题 1 和标题 2 相同。这些不会改变。
4

3 回答 3

2

您可以使用以下方式组合所有内容get_text

test ="""<div id='DIVID'>
<b>Header 1</b>
<br/>
Text 1
<br/>
Text 2
<br/>
Text 3
<br/>
Text 4
<br/>
<b>Header 2</b>
</div>"""

def divid(tag):
    return tag.name=='div' and tag.has_attr('id') and tag['id'].startswith('DIVID')

soup = BeautifulSoup(test)
print soup.find(divid).get_text()

这会给你

标题 1

文本1

文本 2

正文 3

正文 4

标题 2

于 2013-09-27T09:07:11.300 回答
1

你可以尝试这样的事情:

>>> test ="""<b>Header 1</b>
<br/>
Text 1
<br/>
Text 2
<br/>
Text 3
<br/>
Text 4
<br/>
<b>Header 2</b>"""
>>> soup = BeautifulSoup(test)

>>> test = soup.find('b')
>>> desired_text = [x.strip() for x in str(test.parent).split('<br />')]
['<b>Header 1</b>', 'Text 1', 'Text 2', 'Text 3', 'Text 4', '<b>Header 2</b>']

现在你只需要用你的“标题”块来分隔,我认为这是可行的,我相信这可能会让你朝着正确的方向开始。

至于您的另一个问题,您需要组装一个链接列表,然后遍历它们,分别打开每个链接并按照您的意愿进行处理。不过,这是一个更广泛的问题,因此您应该尝试一些东西,然后在您在特定问题上需要一些帮助时回来完善您拥有的东西并提出一个新问题。


最后一行代码的解释:

[x.strip() for x in str(test.parent).split('<br />')]

这需要我在上面分配的“测试”节点并获取父节点。通过变成一个字符串,我可以在<br>标签上“拆分”,这使得这些标签消失并分离出我们想要分离的所有文本。这将创建一个列表,其中每个列表项都有我们想要的文本和一些 '\n'。

最后,最令人困惑的可能是列表解析语法,如下所示:

some_list = [item for item in some_iterable]

这只是产生了一个“项目”列表,所有项目都取自“some_iterable”。在我的列表理解中,我正在遍历列表,获取列表中的每个项目,然后简单地去掉一个换行符(x.strip()部分)。顺便说一句,有很多方法可以做到这一点。

于 2013-09-26T21:27:18.697 回答
1

这是一个不同的解决方案。nextSibling 可以获取结构化文档中遵循命名标记的部分。

from BeautifulSoup import BeautifulSoup

text="""
<b>Header 1</b>
<br/>
Text 1
<br/>
Text 2
<br/>
Text 3
<br/>
Text 4
<br/>
<b>Header 2</b>
"""

soup = BeautifulSoup(text)

for br in soup.findAll('br'):
    following = br.nextSibling
    print following.strip()
于 2013-09-27T07:22:06.903 回答