如何通过网络抓取从维基百科表格中提取数字(或字符串)数据?



我想使用BeautifulSoup从维基百科文章中抓取数据,以创建HR图。对于下面的例子,我选择了名为大角星的恒星,尽管代码的目的是足够通用,可以(几乎?(任何恒星工作。维基百科页面最右边的每颗星星表包含构建图表所需的所有信息。

例如,考虑大角星的维基百科页面。光谱类型可以在Characteristics子标题下找到;绝对量级可以在Astrometry副标题下找到;亮度和温度可以在Details子标题下找到。由于所有这些信息都包含在同一个主表中,因此我尝试了以下方法:

import requests
from bs4 import BeautifulSoup
# import numpy as np
# import matplotlib.pyplot as plt
hyperlink = 'https://en.wikipedia.org/wiki/Arcturus'
webdata = requests.get(hyperlink)
soup = BeautifulSoup(webdata.text, 'lxml')
# print("nPRETTY SOUP:n{}n".format(soup.prettify()))
res = []
right_table = soup.find('table', class_='infobox')
for row in right_table.findAll('tr'):
cells = row.findAll('td')
print("n .. CELLS:n{}n".format(cells))

此代码将为表的每一行运行单独的print命令。我用ctrl + f找到了"温度"这个词的出现,从中找到了相关的print语句:

.. CELLS:
[<td><b><a href="/wiki/Effective_temperature" title="Effective temperature">Temperature</a></b></td>, <td><span class="nowrap"><span data-sort-value="7003428600000000000♠"></span>4286<span style="margin-left:0.3em;margin-right:0.15em;">±</span>30</span><sup class="reference" id="cite_ref-ramirez_prieto_2011_7-3"><a href="#cite_note-ramirez_prieto_2011-7">[7]</a></sup> <a href="/wiki/Kelvin" title="Kelvin">K</a></td>]

实际值为4286 ± 30 K。有没有一种易于概括的方法来解析这个 html 字符串?我相信提取其他相关参数(例如光谱类型(的方法不会有太大区别。

如果你只想提取特定信息,你可以用这个作为例子(使用 CSS 选择器来获取信息(:

import requests
from bs4 import BeautifulSoup
hyperlink = 'https://en.wikipedia.org/wiki/Arcturus'
webdata = requests.get(hyperlink)
soup = BeautifulSoup(webdata.text, 'lxml')
def remove_sup(tag):
for s in tag.select('sup'):
s.extract()
return tag
spectral = remove_sup(soup.select_one(":matches(td, th):contains('Spectral') + td")).get_text(strip=True)
magnitude = remove_sup(soup.select_one(":matches(td, th):contains('Absolute') + td")).get_text(strip=True)
lum = remove_sup(soup.select_one(":matches(td, th):contains('Luminosity') + td")).get_text(strip=True)
temp = remove_sup(soup.select_one(":matches(td, th):contains('Temperature') + td")).get_text(strip=True)
print('{: <25}{}'.format('Spectral type :', spectral))
print('{: <25}{}'.format('Absolute magnitude :', magnitude))
print('{: <25}{}'.format('Luminosity :', lum))
print('{: <25}{}'.format('Temperature :', temp))

指纹:

Spectral type :          K0 III
Absolute magnitude :     −0.30±0.02
Luminosity :             170L☉
Temperature :            4286±30K

您可以使用

for row in right_table.findAll('tr'):
cells = ' '.join([i.get_text() for i in row.findAll('td')])
print(cells)

但是,例如,您将获得超级脚本和子脚本。

最新更新