Выборочная очистка таблиц Википедии с Python - PullRequest
0 голосов
/ 15 мая 2018

У меня проблемы с сортировкой вики-таблицы и надеюсь, что кто-то, кто делал это раньше, может дать мне совет.Из List_of_current_heads_of_state_and_go Government мне нужны страны (работает с кодом ниже), а потом только первое упоминание главы государства + их имена.Я не уверен, как выделить первое упоминание, поскольку все они находятся в одной камере.И моя попытка вытащить их имена дает мне эту ошибку: IndexError: list index out of range.Буду признателен за вашу помощь!

import requests
from bs4 import BeautifulSoup

wiki = "https://en.wikipedia.org/wiki/List_of_current_heads_of_state_and_government"
website_url = requests.get(wiki).text
soup = BeautifulSoup(website_url,'lxml')

my_table = soup.find('table',{'class':'wikitable plainrowheaders'})
#print(my_table)

states = []
titles = []
names = []
for row in my_table.find_all('tr')[1:]:
    state_cell = row.find_all('a')[0]  
    states.append(state_cell.text)
print(states)
for row in my_table.find_all('td'):
    title_cell = row.find_all('a')[0]
    titles.append(title_cell.text)
print(titles)
for row in my_table.find_all('td'):
    name_cell = row.find_all('a')[1]
    names.append(name_cell.text)
print(names)

Желательным выводом будет pandas df:

State | Title | Name |

Ответы [ 3 ]

0 голосов
/ 15 мая 2018

Если бы я мог понять ваш вопрос, то вам нужно получить следующее:

import requests
from bs4 import BeautifulSoup

URL = "https://en.wikipedia.org/wiki/List_of_current_heads_of_state_and_government"

res = requests.get(URL).text
soup = BeautifulSoup(res,'lxml')
for items in soup.find('table', class_='wikitable').find_all('tr')[1::1]:
    data = items.find_all(['th','td'])
    try:
        country = data[0].a.text
        title = data[1].a.text
        name = data[1].a.find_next_sibling().text
    except IndexError:pass
    print("{}|{}|{}".format(country,title,name))

Вывод:

Afghanistan|President|Ashraf Ghani
Albania|President|Ilir Meta
Algeria|President|Abdelaziz Bouteflika
Andorra|Episcopal Co-Prince|Joan Enric Vives Sicília
Angola|President|João Lourenço
Antigua and Barbuda|Queen|Elizabeth II
Argentina|President|Mauricio Macri

И так далее ----

0 голосов
/ 17 апреля 2019

Я ценю, что это старый поток, однако, если кто-то еще хотел сделать то же самое, я нашел очень простой и короткий способ сделать это, импортировав модуль wikipedia python, а затем используя pandas 'read_htmlположить его в кадре данных.Оттуда вы можете применить любой объем анализа, который пожелаете.

Вот мой код, который вызывается из командной строки:

Просто позвоните по python yourfile.py -p Wikipedia_Page_Article_Here

import pandas as pd
import argparse
import wikipedia as wp
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--wiki_page", help="Give a wiki page to get table", required=True)
args = parser.parse_args()
html = wp.page(args.wiki_page).html().encode("UTF-8")
try: 
    df = pd.read_html(html)[1]  # Try 2nd table first as most pages contain contents table first
except IndexError:
    df = pd.read_html(html)[0]
print(df.to_string())

Надеюсь, это кому-нибудь поможет!

ИЛИ без аргументов командной строки:

import pandas as pd
import wikipedia as wp
html = wp.page("List_of_video_games_considered_the_best").html().encode("UTF-8")
try: 
    df = pd.read_html(html)[1]  # Try 2nd table first as most pages contain contents table first
except IndexError:
    df = pd.read_html(html)[0]
print(df.to_string())
0 голосов
/ 15 мая 2018

это не идеально, но почти так работает.

import requests
from bs4 import BeautifulSoup

wiki = "https://en.wikipedia.org/wiki/List_of_current_heads_of_state_and_government"
website_url = requests.get(wiki).text
soup = BeautifulSoup(website_url,'lxml')

my_table = soup.find('table',{'class':'wikitable plainrowheaders'})
#print(my_table)

states = []
titles = []
names = []
""" for row in my_table.find_all('tr')[1:]:
    state_cell = row.find_all('a')[0]  
    states.append(state_cell.text)
print(states)
for row in my_table.find_all('td'):
    title_cell = row.find_all('a')[0]
    titles.append(title_cell.text)
print(titles) """
for row in my_table.find_all('td'):
    try:
        names.append(row.find_all('a')[1].text)
    except IndexError:
        names.append(row.find_all('a')[0].text)

print(names)

В этом списке имен только одна ошибка, которую я могу видеть.Таблица немного сложна из-за исключений, которые вы должны написать.Например, есть имена, которые не являются ссылками, а затем код перехватывает только первую ссылку, найденную в этой строке.Но вам просто нужно написать еще несколько предложений if для таких случаев.По крайней мере, я бы так и сделал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...