Написать пост

Получение данных c веб-сайта без API в 3 строки кода на Python

Аватар Ярослав Сарницкий

Обложка поста Получение данных c веб-сайта без API в 3 строки кода на Python

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

Предположим, что в поисках данных, необходимых для вашего проекта, вы натыкаетесь на такую веб-страницу:

Вот они — все необходимые данные для вашего проекта.

Но что же делать, если нужные вам данные находятся на сайте, который не предоставляет API для их получения? Конечно же, можно потратить несколько часов и написать обработчик, который получит эти данные и преобразует их в нужный для вашего приложения формат.

Но есть и более простое решение — это библиотека Pandas и ее встроенная функция read_html(), которая предназначена для получения данных с html-страниц.

			import pandas as pd

tables = pd.read_html("http://apps.sandiego.gov/sdfiredispatch/")

print(tables[0])
		

Прим. перев. В данной статье используется версия Pandas 0.20.3

Да, все настолько просто. Pandas находит html-таблицы на странице и возвращает их как новый объект DataFrame.

Теперь попробуем указать Pandas, что первая (а точнее нулевая) строка таблицы содержит заголовки столбцов, а также попросим ее сформировать datetime-объект из строки, находящейся в столбце с датой и временем.

			import pandas as pd

calls_df, = pd.read_html("http://apps.sandiego.gov/sdfiredispatch/", header=0, parse_dates=["Call Date"])

print(calls_df)
		

На выходе мы получим следующий результат:

			Call Date        Call Type              Street                             Cross Streets    Unit
0  2017-06-02 17:27:58          Medical         HIGHLAND AV                 WIGHTMAN ST/UNIVERSITY AV     E17
1  2017-06-02 17:27:58          Medical         HIGHLAND AV                 WIGHTMAN ST/UNIVERSITY AV     M34
2  2017-06-02 17:23:51          Medical          EMERSON ST                    LOCUST ST/EVERGREEN ST     E22
3  2017-06-02 17:23:51          Medical          EMERSON ST                    LOCUST ST/EVERGREEN ST     M47
4  2017-06-02 17:23:15          Medical         MARAUDER WY                     BARON LN/FROBISHER ST     E38
5  2017-06-02 17:23:15          Medical         MARAUDER WY                     BARON LN/FROBISHER ST     M41
		

Теперь все эти данные находятся в DataFrame-объекте. Если же нам нужны данные в формате json, добавим еще одну строчку кода:

			import pandas as pd

calls_df, = pd.read_html("http://apps.sandiego.gov/sdfiredispatch/", header=0, parse_dates=["Call Date"])

print(calls_df.to_json(orient="records", date_format="iso"))
		

В результате вы получите данные в формате json с правильным форматированием даты по стандарту ISO 8601:

			[
  {
    "Call Date": "2017-06-02T17:34:00.000Z",
    "Call Type": "Medical",
    "Street": "ROSECRANS ST",
    "Cross Streets": "HANCOCK ST/ALLEY",
    "Unit": "M21"
  },
  {
    "Call Date": "2017-06-02T17:34:00.000Z",
    "Call Type": "Medical",
    "Street": "ROSECRANS ST",
    "Cross Streets": "HANCOCK ST/ALLEY",
    "Unit": "T20"
  },
  {
    "Call Date": "2017-06-02T17:30:34.000Z",
    "Call Type": "Medical",
    "Street": "SPORTS ARENA BL",
    "Cross Streets": "CAM DEL RIO WEST/EAST DR",
    "Unit": "E20"
  }
  // и т.д.
]
		

При желании данные можно сохранить в CSV или XLS:

			import pandas as pd

calls_df, = pd.read_html("http://apps.sandiego.gov/sdfiredispatch/", header=0, parse_dates=["Call Date"])

calls_df.to_csv("calls.csv", index=False)
		

Выполните код и откройте файл calls.csv. Он откроется в приложении для работы с таблицами:

Получение данных c веб-сайта без API в 3 строки кода на Python 1

И, конечно же, Pandas упрощает анализ:

			calls_df.describe()
		

Статистика запроса:

			Call Date Call Type      Street           Cross Streets Unit
count                    69        69          69                      64   69
unique                   29         2          29                      27   60
top     2017-06-02 16:59:50   Medical  CHANNEL WY  LA SALLE ST/WESTERN ST   E1
freq                      5        66           5                       5    2
first   2017-06-02 16:36:46       NaN         NaN                     NaN  NaN
last    2017-06-02 17:41:30       NaN         NaN                     NaN  NaN
		

Группировку:

			calls_df.groupby("Call Type").count()
		

Результат группировки:

			Call Date  Street  Cross Streets  Unit
Call Type
Medical                       66      66             61    66
Traffic Accident (L1)          3       3              3     3
		

И обработку данных:

			calls_df["Unit"].unique()
		

Результат метода unique:

			array(['E46', 'MR33', 'T40', 'E201', 'M6', 'E34', 'M34', 'E29', 'M30',
       'M43', 'M21', 'T20', 'E20', 'M20', 'E26', 'M32', 'SQ55', 'E1',
       'M26', 'BLS4', 'E17', 'E22', 'M47', 'E38', 'M41', 'E5', 'M19',
       'E28', 'M1', 'E42', 'M42', 'E23', 'MR9', 'PD', 'LCCNOT', 'M52',
       'E45', 'M12', 'E40', 'MR40', 'M45', 'T1', 'M23', 'E14', 'M2', 'E39',
       'M25', 'E8', 'M17', 'E4', 'M22', 'M37', 'E7', 'M31', 'E9', 'M39',
       'SQ56', 'E10', 'M44', 'M11'], dtype=object)
		

Теперь вы знаете, как с помощью Python и Pandas можно быстро получить данные с практически любого сайта, не прилагая особых усилий. Освободившееся время предлагаем посвятить чтению других интересных материалов по Python на нашем сайте.

 

Следите за новыми постами
Следите за новыми постами по любимым темам
72К открытий72К показов