Как получить таблицу с сайта python
Перейти к содержимому

Как получить таблицу с сайта python

  • автор:

Парсинг веб-сайтов с помощью pandas и Python с помощью всего нескольких строк кода.

Парсинг веб-сайтов не должен быть сложным, особенно если вы знаете Python.

Динамические веб-сайты можно парсить с помощью таких библиотек, как Selenium, Scrapy и др. Предоставляем вам полное описание библиотек для парсинга сайтов, их преимущества и недостатки в использовании. Простые веб-сайты можно парсить с помощью BeautifulSoup, а сверх простые сайты можно парсить только с помощью pandas.

И нам нужна всего одна или две строки кода, чтобы парсить сайты с pandas.

В этой статье мы собираемся собрать данные из Wikipedia.

Мы извлечем групповые таблицы с чемпионата мира по футболу FIFA 2022. Есть 8 таблиц от группы A до группы H, и мы получим из с помощью нескольких строк кода, используя pandas и Python.

Первое, что необходимо сделать, установить библиотеки и зависимости.

Первым делом мы установим библиотеки pandas и string.

pandas будут использоваться для извлечения данных, а модуль string поможет нам лучше организовать извлеченные данные.

pip install pandas pip install strings

Примечание: Для веб-сканирования с pandas нам также необходимо установить некоторые зависимости, такие как lxml и html5lib (мы можем установить их с помощью pip).

Парсинг сайта (одной строчкой кода)

Простые веб-сайты, такие как Wikipedia, можно легко парсить с помощью одной или двух строк кода с помощью pandas.

Для этого мы сначала должны импортировать pandas. Затем мы должны использовать метод .read_html и в скобках указать веб-сайт, который мы хотим очистить.

import pandas as pd all_tables = pd.read_html("https://en.wikipedia.org/wiki/2022_FIFA_World_Cup")

И это все. Теперь все страницы на сайте Wikipedia хранятся в списке all_tables .

Теперь нам нужно найти таблицы, которые принадлежат группам A, B, …H (всего 8 таблиц). Если мы пройдемся по элементам списка, то увидим, что первая, вторая и третья таблицы находятся в индексах 11, 18 и 25 соответственно.

all_tables[11] all_tables[18] all_tables[25]

Вот так выглядит таблица группы C (индекс 25).

Организация данных

Если мы пройдемся по индексам списка all_tables , мы обнаружим, что первая таблица имеет индекс 11, а следующие таблицы опережают на 7 индексов.

Мы можем связать все эти индексы с названием каждой группы, используя функцию zip .

for letter, i in zip(alphabet, range(11, 67, 7)): print(letter, i)

Вывод будет следующим:

A 11 B 18 C 25 D 32 E 39 F 46 G 53 H 60

Теперь мы знаем, что индекс 11 к группе A, а индекс 60 принадлежит к группе H.

Пришло время лучше организовать таблицы, извлеченные из словаря, чтобы нам больше не приходилось иметь дело с этими индексами. Мы также очистим фреймы данных, переименовав имя второго столбца «Teamvte» и удалив столбец «Qualification».

dict_tables = <> for letter, i in zip(alphabet, range(11, 67, 7)): df = all_tables[i] df.rename(columns=, inplace=True) df.pop('Qualification') dict_tables[f'Group '] = df

Теперь у нас есть все таблицы, хранящиеся в словаре dict_tables . Давайте посмотрим

>>> dict_tables.keys() dict_keys(['Group A', 'Group B', 'Group C', 'Group D', 'Group E', 'Group F', 'Group G', 'Group H'])

Мы можем получить таблицу любой группы, указав ее ключ. Вот как мы это сделаем для группы H.

dict_tables['Group H']

Так выглядит наш результат.

Вы узнали, как парсить сайты с помощью pandas. Вот весь код, который мы написали в этом уроке.

 import pandas as pd from string import ascii_uppercase as alphabet all_tables = pd.read_html("https://en.wikipedia.org/wiki/2022_FIFA_World_Cup") dict_tables = <> for letter, i in zip(alphabet, range(11, 67, 7)): df = all_tables[i] df.rename(columns=, inplace=True) df.pop('Qualification') dict_tables[f'Group '] = df # show all the keys print(dict_tables.keys()) # show table of Group H dict_tables['Group H']

Статья Парсим данные таблиц сайта в Excel с помощью Pandas

Парсинг данных. Эта штука может быть настолько увлекательной, что порой затягивает очень сильно. Ведь всегда интересно найти способ, с помощью которого можно получить те или иные данные, да еще и структурировать их в нужном виде. В статье «Простой пример работы с Excel в Python» уже был рассмотрен один из способов получить данные из таблиц и сохранить их в формате Excel на разных листах. Для этого мы искали на странице все теги, которые так или иначе входят в содержимое таблицы и вытаскивали из них данные. Но, есть способ немного проще. И, давайте, о нем поговорим.

00001.jpg

А состоит этот способ в использовании библиотеки pandas. Конечно же, ее простой не назовешь. Это очень мощный инструмент для аналитики самых разнообразных данных. И в рассмотренном ниже случае мы лишь коснемся небольшого фрагмента из того, что вообще умеет делать эта библиотека.

Что понадобиться?

Для того, чтобы написать данный скрипт нам понадобиться конечно же сам pandas. Библиотеки requests, BeautifulSoup и lxml. А также модуль для записи файлов в формате xlsx – xlsxwriter. Установить их все можно одной командой:

pip install requests bs4 lxml pandas xlsxwriter

А после установки импортировать в скрипт для дальнейшей работы с функциями, которые они предоставляют:

import requests from bs4 import BeautifulSoup import pandas as pd

Так же с сайта, на котором расположены целевые таблицы нужно взять заголовки для запроса. Данные заголовки не нужны для pandas, но нужны для requests. Зачем вообще использовать в данном случае запросы? Тут все просто. Можно и не использовать вовсе. А полученные таблицы при сохранении называть какими-нибудь составными именами, вроде «Таблица 1» и так далее, но гораздо лучше и понятнее, все же собрать данные о том, как называется данная таблица в оригинале. Поэтому, с помощью запросов и библиотеки BeautifulSoup мы просто будем искать название таблицы.

Но, вернемся к заголовкам. Взял я их в инструментах разработчика на вкладке сеть у первого попавшегося запроса.

headers = < 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.174 ' 'YaBrowser/22.1.3.942 Yowser/2.5 Safari/537.36', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,' 'application/signed-exchange;v=b3;q=0.9 ' >

Теперь нужен список, в котором будут перечисляться года, которые представлены в виде таблиц на сайте. Эти года получаются из псевдовыпадающего списка. Я не стал использовать selenium для того, чтобы получить их со страницы. Так как обычный запрос не может забрать эти данные. Они подгружаются с помощью JS скриптов. В данном случае не так уж много данных, которые надо обработать руками. Поэтому я создал список, в которые эти данные и внес вручную:

num_year_dict = ['443', '442', '441', '440', '439', '438', '437', '436', '435', '434', '433', '432', '431', '426', '425', '1', '2', '165', '884', '1851', '3226', '4385', '4959', '5582', '6297', '6886', '7371', '8071', '8671']

Теперь нам нужно будет создать пустой словарь вне всяких циклов. Именно, чтобы он был глобальной переменной. Этот словарь мы и будем наполнять полученными данными, а также сохранять их него данные в таблицу Excel. Поэтому, я подумал, что проще сделать его глобальной переменной, чем тасовать из функции в функцию.

Назвал я его df, потому как все так называют. И увидев данное название в нужном контексте становиться понятно, что используется pandas. df – это сокращение от DataFrame, то есть, определенный набор данных.

Ну вот, предварительная подготовка закончена. Самое время получать данные. Давайте для начала сходим на одну страницу с таблицей и попробуем получить оттуда данные с помощью pandas.

Здесь была использована функция read_html. Pandas использует библиотеку для парсинга lxml. То есть, примерно это все работает так. Получаются данные со страницы, а затем в коде выполняется поиск с целью найти все таблицы, у которых есть тэг table>, а далее, внутри таблиц ищутся заголовки и данные под тэгами tr> и td>, которые и возвращаются в виде списка формата DataFrame.

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

И видим, что найденных таблиц две. Если вывести по очереди элементы списка, то мы увидим, что нужная нам таблица, в данном случае, находиться под индексом 1. Вот ее и распечатаем для просмотра:

И вот она полученная таблица:

Полученная в запросе таблица

screenshot1.png

Как видим, в данной таблице помимо нужных нам данных, содержится так же лишний столбец, от которого желательно избавиться. Это, скажем так, можно назвать сопутствующим мусором. Поэтому, полученные данные иногда надо «причесать». Давайте вызовем метод drop и удалим ненужный нам столбец.

tables[1].drop(‘Unnamed: 0’, axis=1, inplace=True)

На то, что нужно удалить столбец указывает параметр axis, который равен 1. Если бы нужно было удалить строку, он был бы равен 0. Ну и указываем название столбца, который нужно удалить. Параметр inplace в значении True указывает на то, что удалить столбец нужно будет в исходных данных, а не возвращать нам их копию с удаленным столбцом.

А теперь нужно получить заголовок таблицы. Поэтому, делаем запрос к странице, получаем ее содержимое и отправляем для распарсивания в BeautifulSoup. После чего выполняем поиск названия и обрезаем из него все лишние данные.

url = f'https://www.sports.ru/rfpl/table/?s=&table=0&sub=table' req = requests.get(url=url, headers=headers) soup = BeautifulSoup(req.text, 'lxml') title_table = soup.find('h2', class_='titleH3').text.split("-")[2].strip().replace("/", "_")

Теперь, когда у нас есть таблица и ее название, отправим полученные значения в ранее созданный глобально словарь.

Вот и все. Мы получили данные по одной таблице. Но, не будем забывать, что их больше тридцати. А потому, нужен цикл, чтобы формировать ссылки из созданного ранее списка и делать запросы уже к страницам по ссылке. Давайте полностью оформим код функции. Назовем мы ее, к примеру, get_pd_table(). Ее полный код состоит из всех тех элементов кода, которые мы рассмотрели выше, плюс они запущены в цикле.

Код функции для получения данных из таблиц и добавления их в словарь

def get_pd_table(): for num in num_year_dict: url = f'https://www.sports.ru/rfpl/table/?s=&table=0&sub=table' req = requests.get(url=url, headers=headers) soup = BeautifulSoup(req.text, 'lxml') title_table = soup.find('h2', class_='titleH3').text.split("-")[2].strip().replace("/", "_") print(f'Получаю данные из таблицы: "". ') tables = pd.read_html(url) tables[1].drop('Unnamed: 0', axis=1, inplace=True) df[title_table] = tables[1]

Итак, когда цикл пробежится по всем ссылкам у нас будет готовый словарь с данными турниров, которые желательно бы записать на отдельные листы. На каждом листе по таблице. Давайте сразу создадим для этого функцию pd_save().

writer = pd.ExcelWriter(‘./Турнирная таблица ПЛ РФ.xlsx’, engine=’xlsxwriter’)

Создаем объект писателя, в котором указываем имя записываемой книги, и инструмент, с помощью которого будем производить запись в параметре engine=’xlsxwriter’.

После запускаем цикл, в котором создаем объекты, то есть листы для записи из ключей списка с таблицами df, указываем, с помощью какого инструмента будет производиться запись, на какой лист. Имя листа берется из ключа словаря. А также указывается параметр index=False, чтобы не сохранялись индексы автоматически присваиваемые pandas.

df[df_name].to_excel(writer, sheet_name=df_name, index=False)

Ну и после всего сохраняем книгу:

Полный код функции сохранения значений:

def pd_save(): writer = pd.ExcelWriter('./Турнирная таблица ПЛ РФ.xlsx', engine='xlsxwriter') for df_name in df.keys(): print(f'Записываем данные в лист: ') df[df_name].to_excel(writer, sheet_name=df_name, index=False) writer.save()

Вот и все. Для того, чтобы было не скучно ждать, пока будет произведен парсинг таблиц, добавим принты с информацией о получаемой таблице в первую функцию.

print(f’Получаю данные из таблицы: «». ‘)

И во вторую функцию, с сообщением о том, данные на какой лист записываются в данный момент.

print(f’Записываем данные в лист: ‘)

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

Полный код скрипта парсинга таблиц в excel с помощью pandas

import requests from bs4 import BeautifulSoup import pandas as pd headers = < 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.174 ' 'YaBrowser/22.1.3.942 Yowser/2.5 Safari/537.36', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,' 'application/signed-exchange;v=b3;q=0.9 ' >num_year_dict = ['443', '442', '441', '440', '439', '438', '437', '436', '435', '434', '433', '432', '431', '426', '425', '1', '2', '165', '884', '1851', '3226', '4385', '4959', '5582', '6297', '6886', '7371', '8071', '8671'] df = <> def get_pd_table(): for num in num_year_dict: url = f'https://www.sports.ru/rfpl/table/?s=&table=0&sub=table' req = requests.get(url=url, headers=headers) soup = BeautifulSoup(req.text, 'lxml') title_table = soup.find('h2', class_='titleH3').text.split("-")[2].strip().replace("/", "_") print(f'Получаю данные из таблицы: "". ') tables = pd.read_html(url) tables[1].drop('Unnamed: 0', axis=1, inplace=True) df[title_table] = tables[1] def pd_save(): writer = pd.ExcelWriter('./Турнирная таблица ПЛ РФ.xlsx', engine='xlsxwriter') for df_name in df.keys(): print(f'Записываем данные в лист: ') df[df_name].to_excel(writer, sheet_name=df_name, index=False) writer.save() def main(): get_pd_table() print(' ') pd_save() print('\n[+] Данные записаны!') if __name__ == '__main__': main()

И ниже результат работы скрипта с уже полученными и записанными таблицами:

Полученная в запросе таблица

screenshot2.png

Как видите, использовать библиотеку pandas, по крайней мере в данном контексте, не очень сложно. Конечно же, это только самая малая часть того, что она умеет. А умеет она собирать и анализировать данные из самых разных форматов, включая такие распространенные, как: cvs, txt, HTML, XML, xlsx.

Ну и думаю, что не всегда данные будут прилетать «чистыми». Скорее всего, периодически будут попадаться мусорные столбцы или строки. Но их не особо то трудно удалить. Нужно только понимать, что и откуда.

В общем, для себя я сделал однозначный вывод – если мне понадобиться парсить табличные значения, то лучше, чем использование pandas, пожалуй и не придумаешь. Можно просто на лету формировать данные из одного формата и переводить тут же в другой без утомительного перебора. К примеру, из формата csv в json.

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна

Нужно спарсить таблицу с сайта?

Здравствуйте! Я начинающий программист и мне нужно спарсить таблицу с сайта —> https://opi.dfo.kz/p/ru/DfoObjects/objects/teaser-.
Честно говоря не понимаю как ее спарсить уже ломаю голову 3 часа, прошу помочь разобраться или иначе я сам не смогу понять, что тут делать, я гуглил смотрел как делают другие, но взрыв мозга.

  • Вопрос задан более трёх лет назад
  • 1385 просмотров

9 комментариев

Простой 9 комментариев

kshnkvn

Ну таблица как таблица, берешь и парсишь, с чем проблема то?

SeRzZzJ

Сергей Романюк @SeRzZzJ Автор вопроса
Ivan Yakushenko, я не понимаю как к тегам таблицы обратится
а как вы пробуете и что конкретно у вас не получается?

SeRzZzJ

Сергей Романюк @SeRzZzJ Автор вопроса

Stanislav Pugachev, мне нужно разбить в несколько словарей значения как в таблице, допустим как на сайте тип —> физическое лицо и записать в excel документ и я уже ломаю голову слишком долго как это осуществить

kshnkvn

SeRzZzJ, ты видимо не понял к чему мы клоним. Поясню цитатой из правил п. 5.12 данного ресурса:

В отличие от вопроса, задача и задание представляют собой частную проблемную ситуацию с явно заданной целью, которую необходимо достичь. Пользу от достижения этой цели получает, как правило, лишь её автор. И даже автору решение задачи или задания будет полезно лишь кратковременно (до тех пор, пока он не использует полученное решение). Все остальные пользователи, которые будут просматривать вопрос, сведенный к решению частной задачи, в надежде найти ответ на свой, лишь понапрасну затратят время. Поэтому, чтобы такие вопросы-задания не мешали другим пользователям искать ответы на вопросы, нам приходится их удалять. А для поиска помощи в решении задач и выполнения заданий мы рекомендуем использовать специализированные сервисы, например «Хабр Фриланс».

Пока ты не предоставишь собственные попытки решения своей собственной проблемы, твой «вопрос» расценивается как задание, что запрещено правилами данного ресурса.

SeRzZzJ

Сергей Романюк @SeRzZzJ Автор вопроса

Ivan Yakushenko, есть код, но работает криво и не правильно, я получаю всю информацию без разделения в один словарь, а как сделать иначе хотел узнать тут

kshnkvn

SeRzZzJ, да что же до тебя вся никак не доходит: код свой покажи, который ты написал, но неправильно и тогда тебе подскажут (может быть) как нужно было сделать правильно. В этом и суть подобных ресурсов, а не что бы «сделайте за меня».

SeRzZzJ

Сергей Романюк @SeRzZzJ Автор вопроса

Ivan Yakushenko,
import requests
from bs4 import BeautifulSoup
import csv
from fake_useragent import UserAgent

# get html page
def get_html(url, params=»):
r = requests.get(URL, headers=HEADERS, params=params)
return r

# we get the content of the html page
def get_content(html):
soup = BeautifulSoup(html.text, ‘html.parser’)
items = soup.find_all(‘table’, class_=’dsnode-table’)
faces = []
for item in items:
faces.append( ‘info’: item.find(‘tbody’).get_text(strip=True)
>)
return faces

#
def parser():
html = get_html(URL)
print(get_content(html))

if __name__ == ‘__main__’:
parser()

phaggi

Алан Гибизов @phaggi Куратор тега Python

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

Нужно уважать тех, от кого ты зависишь, и любить тех, кто от тебя зависит. А так, как делаешь ты. ничего хорошего у тебя не выйдет.

Решения вопроса 1

hottabxp

Сергей Карбивничий @hottabxp Куратор тега Python
Сначала мы жили бедно, а потом нас обокрали..

import requests from bs4 import BeautifulSoup from lxml import html import csv headers = url = 'https://opi.dfo.kz/p/ru/DfoObjects/objects/teaser-view/25720?RevisionId=0&ReportNodeId=2147483637&PluginId=6c2aa36248f44fd7ae888cb43817d49f&ReportId=61005620' response = requests.get(url,headers=headers) file = open('data.csv','w') # Открываем файл на запись. Можно было использовать контекстный менеджер, но так думаю проще. writer = csv.writer(file) # Передаем в функцию writer дескриптор открытого файла. soup = BeautifulSoup(response.text,"html.parser") rows = soup.find('table',class_='dsnode-table').find('tbody').find_all('tr') # Ищем в html тег 'table' с классом 'dsnode-table', # далее в найденом ищем тег 'tbody' и наконец ищем все теги 'tr'. Тег 'tr' в html это тег строки таблицы. В результате, в rows # у нас окажутся все теги 'tr', тоесть все строки таблицы. for row in rows: # Проходимся по всем строкам. При каждой итерации, в row у нас будет следующая строка таблицы, вместе с html тегами. columns = row.find_all('td') # Ищем в текущей строке таблици все теги 'td'. В html td - это тег ячейки. data_list = [columns[0].text,columns[1].text,columns[2].text,columns[3].text,columns[4].text,columns[5].text,columns[6].text,columns[7].text,columns[8].text] # Так как в каждой строке 9 ячеек, а элементы списка в большинстве ЯП нумеруюются с нуля, то мы можем обратится к конкретной ячейке # текущей строки по индексу. Первая ячейка будет columns[0], а последняя, тоесть девятая - columns[8]. Создаем список 'data_list', # и заносим в него все ячейки текущей строки. Но, так как в columns кроме текстовых данных также присутствуют html теги, мы обращаемся # к свойству .text, что-бы получить сам текст, без тегов. writer.writerow(data_list) # Записываем текущую строку в csv файл. # Далее цикл продолжается, пока не достигнет конца таблицы(условно, так как все строки таблици мы уже получили, и они хранятся в 'rows') file.close() # Так как мы не используем контекстный менеджер with, обязательно закрываем открытый файл.

Парсинг таблицы сайта

собственно здесь я все это ищу

Не могу разобраться, как можно спарсить таблицу на этом сайте https://coronavirus-graph.ru/rossiya/moskva Дело в том, что я хочу создать список, в котором будет отображаться статистика по дням: Дата, Заражений всего, Умерло, всего, Летальность, Выздоровело всего, Болеющих

import requests from bs4 import BeautifulSoup URL = 'https://coronavirus-graph.ru/rossiya/moskva' def get_html(url, params=None): r = requests.get(url, params=params) return r def get_content(html): soup = BeautifulSoup(html, 'html.parser') items = soup.find_all('div', class_='stat_table_box') people = [] for item in items: people.append(< 'title': item.find('tbody') .get_text() >) print(people) def parse(): html = get_html(URL) if html.status_code == 200: get_content(html.text) else: print('Error') 

Отслеживать

задан 5 ноя 2021 в 1:22

Тимофей Рудковский Тимофей Рудковский

19 7 7 бронзовых знаков

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Если использование BeautifulSoup не есть принципиальным, то можно использовать pandas, который как раз для этого и предназначен (и не только). И код прям в две строки

>>> import pandas >>> ds = pandas.read_html("https://coronavirus-graph.ru/rossiya/moskva") >>> ds [ Дата Заражений всего Умерло всего Летальность Выздоровело всего Болеющих 0 4 ноября 18433626305 3172897 0.05% 16186246633 ➜193 010-425 1 3 ноября 18370576827 3163195 0.05% 16119916628 ➜193 435+104 2 2 ноября 18302305736 3153698 0.05% 16053636359 ➜193 331-721 3 1 ноября 18244947103 3143896 0.05% 15990045257 ➜194 052+1750 4 31 октября 18173917603 3134294 0.05% 15937475050 ➜192 302+2459 .. . . . . . . 594 20 марта 13133 — — 1 ➜130+33 595 19 марта 9812 — — 1 ➜97+12 596 18 марта 8631 — — 1 ➜85+31 597 17 марта 551 — — 1 ➜54+1 598 16 марта 5420 — — 1 ➜53+20 [599 rows x 6 columns]] 

а теперь эти все данные уже находятся в удобной структуре и с ними можно делать все, что угодно. А если почитать документацию на pandas, то будет просто чудесно.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *