【问题标题】:Navigating to second string text using BeautifulSoup使用 BeautifulSoup 导航到第二个字符串文本
【发布时间】:2014-09-15 10:12:00
【问题描述】:

这里是lxml,保存为sample.html。

<html> 
    <body> 
    <div class ="ecopyramid"> 
        <ul id ="producers"> 
            <li class ="producerlist"> 
                <div class ="name">A1</div> 
                <div class ="number">100000</div> 
            </li> 
            <li class ="producerlist"> 
                <div class ="name">B1</div> 
                <div class ="number">100000</div> 
            </li> 
        </ul> 
        <ul id ="primaryconsumers"> 
            <li class ="primaryconsumerlist"> 
                <div class ="name">A2</div> 
                <div class ="number">1000</div> 
            </li> 
            <li class ="primaryconsumerlist"> 
                <div class ="name">B2</div> 
                <div class ="number">2000</div> 
            </li> 
        </ul> 
        <ul id ="secondaryconsumers"> 
            <li class ="secondaryconsumerlist"> 
                <div class ="name">A3</div> 
                <div class ="number">100</div> 
            </li>

            <li class ="secondaryconsumerlist"> 
                <div class ="name">B3</div> 
                <div class ="number">98</div>
            </li> 
        </ul> 
        <ul id ="tertiaryconsumers"> 
            <li class ="tertiaryconsumerlist"> 
                <div class ="name">A4</div> 
                <div class ="number">80</div> 
            </li> 
            <li class ="tertiaryconsumerlist"> 
                <div class ="name">B4</div> 
                <div class ="number">50</div> 
            </li> 
        </ul> 
    </body> 
</html>

以下是浏览上述 sample.html 的代码:

from bs4 import BeautifulSoup

with open("sample.html", "r") as sample_pyramid:
    soup=BeautifulSoup(sample_pyramid, "lxml")

soup_object = soup.find("ul", id="secondaryconsumers")
print soup_object.li.div.string

因此,在这段代码中,我可以首先通过标签“ul”和 id “secondaryconsumers”指定文本“A3”的父位置,然后在打印命令中通过“.li.div”进一步指定.string" 后缀并输出所需的 "A3" 文本。我的问题如下:

1) 在本例中,我如何编写代码以调用/打印文本“B3”?

2) 在本例中,我如何编码以调用/打印文本“98”(“B3”下方)?

我尝试了很多都没有成功,我可以通过导航调用第一个文本对象,但不能调用共享标签中的第二个文本对象。

有什么想法吗?

【问题讨论】:

    标签: python python-2.7 html-parsing beautifulsoup text-extraction


    【解决方案1】:

    您可以使用CSS selectors 获取姓名和号码:

    names = soup.select('ul#secondaryconsumers > li.secondaryconsumerlist > div.name')
    numbers = soup.select('ul#secondaryconsumers > li.secondaryconsumerlist > div.number')
    
    print [name.text for name in names]
    print [number.text for number in numbers]
    

    打印:

    [u'A3', u'B3']
    [u'100', u'98']
    

    cmets中后续问题的示例代码:

    from bs4 import BeautifulSoup
    
    
    data = """
    <div class="span9">
        <table class="result-data table" border="0">
            <tbody>
            <tr class="result-item highlighting">
                <td class="result-category" scope="row">Name:</td>
                <td class="result-value-bold" colspan="4" itemprop="item">
                    Robin Hood
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    """
    
    soup = BeautifulSoup(data)
    print soup.find('td', class_="result-value-bold").get_text(strip=True)
    

    打印Robin Hood

    或者,也可以先找到父级tabletr

    table = soup.find('table', class_='result-data')
    tr = table.find('tr', class_='result-item')
    print tr.find('td', class_="result-value-bold").get_text(strip=True)
    

    【讨论】:

    • 感谢 Alecxe,一个后续问题,在您的打印命令中,它使用了一个 for 循环,是否可以只打印第二个,所以它只打印出“98”?
    • @KubiK888 当然,您只想从上面的 html 中获取 98,对吧?它总是在第二个 li 内,类 secondaryconsumerlist 吗?谢谢。
    • 两部分问题:1)是的,它总是在第二个“li”内,类“secondaryconsumerlist”,我怎样才能打印/返回那个值而不是全部? 2)我尝试在真实站点中应用CSS选择器方法,结果发现class或id属性中有空格和连字符,例如
    • ,有没有办法为了修改 BeautifulSoup 中的 CSS 选择器,我尝试阅读您提到的文档链接,但找不到任何解决方案。
  • @KubiK888 这绝对是可以解决的。为了清楚起见,你能提供来自真实网站的 html 吗?只是&lt;div class ="ecopyramid"&gt;...&lt;/div&gt; 部分。
  • 名称: Robin Hood
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签