你如何使用BeautifulSoup根据孩子和兄弟姐妹选择一个标签?

时间:2016-12-04 16:47:55

标签: python python-3.x web-scraping beautifulsoup

我试图从2012年奥巴马 - 罗姆尼总统辩论中提取引用。问题是the site组织得不好。所以结构看起来像这样:

<span class="displaytext">
    <p>
        <i>OBAMA</i>Obama's first quotes
    </p>
    <p>More quotes from Obama</p>
    <p>Some more Obama quotes</p>

    <p>
        <i>Moderator</i>Moderator's quotes
    </p>
    <p>Some more quotes</p>

    <p>
        <i>ROMNEY</i>Romney's quotes
    </p>
    <p>More quotes from Romney</p>
    <p>Some more Romney quotes</p>
</span>

有没有办法选择一个<p>,其第一个孩子是i,其中包含OBAMA文字以及所有p兄弟姐妹,直到下一个p 1}},其第一个孩子是i,没有文字Obama ??

这是我到目前为止所尝试的内容,但它只是抓住第一个忽略兄弟姐妹的p

input = '''<span class="displaytext">
        <p>
            <i>OBAMA</i>Obama's first quotes
        </p>
        <p>More quotes from Obama</p>
        <p>Some more Obama quotes</p>

       <p>
           <i>Moderator</i>Moderator's quotes
       </p>
       <p>Some more quotes</p>

       <p>
           <i>ROMNEY</i>Romney's quotes
       </p>
       <p>More quotes from Romney</p>
       <p>Some more Romney quotes</p>
       </span>'''

soup = BeautifulSoup(input)
debate_text = soup.find("span", { "class" : "displaytext" })
president_quotes = debate_text.find_all("i", text="OBAMA")

for i in president_quotes:
    siblings = i.next_siblings
    for sibling in siblings:
        print(sibling)

仅打印Obama's first quotes

2 个答案:

答案 0 :(得分:2)

我认为一种类似finite state machine的解决方案可以在这里使用。像这样:

// @require http://code.jquery.com/jquery-latest.js
// @require https://raw.githubusercontent.com/js-cookie/js-cookie/master/src/js.cookie.js

答案 1 :(得分:2)

其他奥巴马引用是p的兄弟姐妹,而不是i,因此您需要找到i父母的兄弟姐妹。当您在这些兄弟姐妹中循环时,您可以在拥有i时停止。像这样:

for i in president_quotes:
    print(i.next_sibling)
    siblings = i.parent.find_next_siblings('p')
    for sibling in siblings:
        if sibling.find("i"):
            break
        print(sibling.string)

打印:

Obama's first quotes

More quotes from Obama
Some more Obama quotes