我想获取参议员的年龄、出生地和以前的职业。 每个参议员的信息都可以在维基百科上找到,在他们各自的页面上,还有另一个页面有一个表格,上面列出了所有参议员的名字。 我如何浏览该列表,通过链接访问每位参议员的相应页面,并获取我想要的信息?
这是我到目前为止所做的。
1 。 (没有 python)发现 DBpedia 存在并编写了一个查询来搜索参议员。不幸的是,DBpedia 没有对其中的大部分(如果有的话)进行分类:
SELECT ?senator, ?country WHERE { ?senator rdf:type <http://dbpedia.org/ontology/Senator> . ?senator <http://dbpedia.org/ontology/nationality> ?country }
查询results不尽如人意。
2。发现有一个名为 wikipedia
的 python 模块允许我从各个 wiki 页面搜索和检索信息。通过查看超链接,使用它从表中获取参议员姓名列表。
import wikipedia as w
w.set_lang('pt')
# Grab page with table of senator names.
s = w.page(w.search('Lista de Senadores do Brasil da 55 legislatura')[0])
# Get links to senator names by removing links of no interest
# For each link in the page, check if it's a link to a senator page.
senators = [name for name in s.links if not
# Senator names don't contain digits nor ,
(any(char.isdigit() or char == ',' for char in name) or
# And full names always contain spaces.
' ' not in name)]
此时我有点迷茫。这里的列表 senators
包含所有参议员姓名,但也包含其他姓名,例如党派姓名。 wikipidia
模块(至少从我在 API 文档中可以找到的)也没有实现跟踪链接或搜索表格的功能。
我在 StackOverflow 上看到了两个相关的条目,它们似乎很有帮助,但它们(here 和 here)都从一个页面中提取信息。
谁能指出我的解决方案?
谢谢!
最佳答案
好的,所以我想通了(感谢将我指向 BeautifulSoup 的评论)。
实现我想要的其实没有什么大 secret 。我只需要使用 BeautifulSoup 浏览列表并存储所有链接,然后使用 urllib2
打开每个存储的链接,在响应中调用 BeautifulSoup,然后……完成。这是解决方案:
import urllib2 as url
import wikipedia as w
from bs4 import BeautifulSoup as bs
import re
# A dictionary to store the data we'll retrieve.
d = {}
# 1. Grab the list from wikipedia.
w.set_lang('pt')
s = w.page(w.search('Lista de Senadores do Brasil da 55 legislatura')[0])
html = url.urlopen(s.url).read()
soup = bs(html, 'html.parser')
# 2. Names and links are on the second column of the second table.
table2 = soup.findAll('table')[1]
for row in table2.findAll('tr'):
for colnum, col in enumerate(row.find_all('td')):
if (colnum+1) % 5 == 2:
a = col.find('a')
link = 'https://pt.wikipedia.org' + a.get('href')
d[a.get('title')] = {}
d[a.get('title')]['link'] = link
# 3. Now that we have the links, we can iterate through them,
# and grab the info from the table.
for senator, data in d.iteritems():
page = bs(url.urlopen(data['link']).read(), 'html.parser')
# (flatten list trick: [a for b in nested for a in b])
rows = [item for table in
[item.find_all('td') for item in page.find_all('table')[0:3]]
for item in table]
for rownumber, row in enumerate(rows):
if row.get_text() == 'Nascimento':
birthinfo = rows[rownumber+1].getText().split('\n')
try:
d[senator]['birthplace'] = birthinfo[1]
except IndexError:
d[senator]['birthplace'] = ''
birth = re.search('(.*\d{4}).*\((\d{2}).*\)', birthinfo[0])
d[senator]['birthdate'] = birth.group(1)
d[senator]['age'] = birth.group(2)
if row.get_text() == 'Partido':
d[senator]['party'] = rows[rownumber + 1].getText()
if 'Profiss' in row.get_text():
d[senator]['profession'] = rows[rownumber + 1].getText()
很简单。 BeautifulSoup 创造奇迹 =)
关于python - 如何使用 python 从多个维基百科页面抓取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39299658/