按顺序从HTML中提取数据

时间:2018-04-05 23:50:51

标签: python beautifulsoup html-parsing

如何从维基百科页面中提取所有表格内容和先前数据,例如https://en.wikipedia.org/wiki/List_of_birds_of_Trinidad_and_Tobago,其中数据采用这种重复格式,

 <p>
  <b>
   Order
  </b>
  :
  <a class="mw-redirect" href="/wiki/Passeriformes" title="Passeriformes">
   Passeriformes
  </a>
  <span class="nowrap">
  </span>
  <b>
   Family
  </b>
  :
  <a class="mw-redirect" href="/wiki/Passeridae" title="Passeridae">
   Passeridae
  </a>
 </p>
 <p>
  <a href="/wiki/Sparrow" title="Sparrow">
   Sparrows
  </a>
  are small passerine birds ...
 </p>
 <table class="wikitable" width="72%">
  <tr>
   <th width="24%">
    Common name
   </th>
   <th width="24%">
    Binomial
   </th>
   <th width="24%">
    Status
   </th>
  </tr>
  <tr>
   <td>
    <a href="/wiki/House_sparrow" title="House sparrow">
     House sparrow
    </a>
   </td>
   <td>
    <i>
     Passer domesticus
    </i>
   </td>
   <td>
    Trinidad only - Introduced species
   </td>
  </tr>
 </table>

所需的输出格式是

订单,家庭,描述,名称,二项式,状态。

1 个答案:

答案 0 :(得分:1)

的方法:

所有想要的标签都是彼此的兄弟姐妹。所以,基本上,你必须使用find_next_sibling()函数来找到它们。

说明:

鸟类的所有名称(标题)都位于index = pd.date_range(df.index.min() - pd.Timedelta(1, unit='d'), df.index.max() + pd.Timedelta(1, unit='d'))[::-1] res = df.reindex(index) print (res) 1 2 3 2001-01-26 NaN NaN NaN 2001-01-25 1364.3 1367.35 1354.63 2001-01-24 1360.4 1369.75 1357.28 2001-01-23 1342.9 1362.90 1339.63 2001-01-22 NaN NaN NaN 标记内。但是,第一个<h2>标记用于<h2>(因此请跳过)。 订单系列位于Contents标记之后的<p>标记内。你可以使用<h2>找到它。可以使用h2.find_next_sibling('p')找到包含名称二项状态的表。

使用这一切,您可以打印所需的所有细节。但是,当您到达包含引用h2.find_next_sibling('table')标记时,您必须打破循环。这可以使用

完成
<h2>

代码:

if h2.find('span', class_='mw-headline').text == 'References':
    break

部分输出:

r = requests.get('https://en.wikipedia.org/wiki/List_of_birds_of_Trinidad_and_Tobago')
soup = BeautifulSoup(r.text, 'lxml')

for bird in soup.find_all('h2')[1:]:
    title = bird.find('span', class_='mw-headline').text
    if title == 'References':
        break
    print(title)
    p_tag = bird.find_next_sibling('p')
    order, family = [x.text for x in p_tag.find_all('a')]
    table = p_tag.find_next_sibling('table')
    for row in table.find_all('tr')[1:]:
        name, binomial, status = [x.text for x in row.find_all('td')]
        print(order, family, name, binomial, status, sep=' | ')
    print()