2016-09-02 11 views
4

私は、年齢、出身地、上院議員の以前の職業を取得したいと思います。 それぞれの上院議員の情報は、それぞれのページでWikipediaで入手できます。また、その名前ですべての上院議員を一覧表示する別のページがあります。 どうすればそのリストを見て、各上院議員のそれぞれのページへのリンクをたどり、私が望む情報を得ることができますか?pythonで複数のwikipediaページからデータをスクラップする方法は?

ここまでは私がこれまで行ってきたことです。

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。私が個々のwikiページから情報を検索して取り出すことを可能にするwikipediaと呼ばれるPythonモジュールがあることを知りました。ハイパーリンクを見て、テーブルから上院議員名のリストを取得するために使用しました。

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で2つの関連エントリが役に立つと思われますが、両方とも(herehere)は1つのページから情報を抽出します。

誰も私に解決策を教えてもらえますか?

ありがとうございます!

+2

美しいスープ! – benten

+0

@ user2241910では、BeautifulSoupを使用して目的のWebサイトをスクラップし、興味のあるデータを抽出できると示唆しています。 – albert

答えて

0

私はそれを考え出しました(私にBeautifulSoupを指し示すコメントのおかげで)。

実際に私が望むことを達成するための大きな秘密はありません。私は、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 works wonder =)

関連する問題