首页 > 解决方案 > 如何在beautifulsoup中使用-soup-contains获得选择的下一个兄弟姐妹

问题描述

意图 我正在从Wikipedia中提取有关所有国家/地区的数据。我希望我的解析器足够通用,适用于所有国家。

假设我现在正在从所有国家/地区提取 GDP(购买力平价)。在Wikipedia中,它们被放置在 infoBox 表中。问题是 GDP(PPP) 在表中的 3 个不同行中被拆分。

这是结构:

   <th scope="row" class="infobox-label">
                              <a href="/wiki/Gross_domestic_product" title="Gross domestic product">GDP</a>&#160;
                              <style data-mw-deduplicate="TemplateStyles:r886047488">.mw-parser-output .nobold{font-weight:normal}</style>
                              <span class="nobold">(<a href="/wiki/Purchasing_power_parity" title="Purchasing power parity">PPP</a>)</span>
                           </th>
                           <td class="infobox-data">2020&#160;estimate</td>
                        </tr>
                        <tr class="mergedrow">
                           <th scope="row" class="infobox-label">
                              <div class="ib-country-fake-li">•&amp;#160;Total</div>
                           </th>
                           <td class="infobox-data"><img alt="Increase" src="//upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/11px-Increase2.svg.png" decoding="async" title="Increase" width="11" height="11" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/17px-Increase2.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/22px-Increase2.svg.png 2x" data-file-width="300" data-file-height="300" /> $1.391 trillion<sup id="cite_ref-IMFWEOEG_10-0" class="reference"><a href="#cite_note-IMFWEOEG-10">&#91;10&#93;</a></sup>&#32;(<a href="/wiki/List_of_countries_by_GDP_(PPP)" title="List of countries by GDP (PPP)">20th</a>)</td>
                        </tr>
                        <tr class="mergedbottomrow">
                           <th scope="row" class="infobox-label">
                              <div class="ib-country-fake-li">•&amp;#160;Per capita</div>
                           </th>
                           <td class="infobox-data"><img alt="Increase" src="//upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/11px-Increase2.svg.png" decoding="async" title="Increase" width="11" height="11" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/17px-Increase2.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Increase2.svg/22px-Increase2.svg.png 2x" data-file-width="300" data-file-height="300" /> $14,023<sup id="cite_ref-IMFWEOEG_10-1" class="reference"><a href="#cite_note-IMFWEOEG-10">&#91;10&#93;</a></sup>&#32;(<a href="/wiki/List_of_countries_by_GDP_(PPP)_per_capita" title="List of countries by GDP (PPP) per capita">92nd</a>)</td>
                        </tr>

这是我到目前为止所尝试的:

site= "http://en.wikipedia.org/wiki/Brazil"
country = requests.get(site)
countryPage = BeautifulSoup(country.content, "html.parser")
infoBox = countryPage.find("table", class_="infobox ib-country vcard")
#find GDP PPP
tds = infoBox.select('th:-soup-contains("PPP") + tr')
print(tds)

问题 尽管使用“+ tr”作为 CSS 选择器,但该代码会打印 GDP PPP 本身的行,而不是后面的行。

谁能告诉我我做错了什么?如何在我使用 CSS 选择器找到的那一行之后选择表行?

标签: pythonweb-scrapingbeautifulsoupcss-selectorswikipedia

解决方案


beautifulsoup4 4.9.3- 要选择下一个兄弟姐妹<tr>,您可以选择:

soup.select_one('tr:has(th:-soup-contains("PPP"))~tr')

或者你想要他们两个:

soup.select('tr:has(th:-soup-contains("PPP"))~tr')[:2]

要获取文本:

[x.text for x in soup.select('tr:has(th:-soup-contains("PPP"))~tr')[:2]]

推荐阅读