Pandas: чтение HTML-таблиц

Pandas'pd.read_html()Функция может автоматически парсить данные HTML-таблиц на веб-страницах и преобразовывать их в DataFrame. Это очень полезно в таких сценариях, как веб-скрейпинг, анализ цен на акции и получение финансовой информации.


Базовое использование

read_html()Функция находит и читает все элементы HTML-таблиц на веб-странице, возвращая список объектов DataFrame.

Чтение одной таблицы

Пример

import pandas as pd

# Прочитать все таблицы на веб-странице
# Примечание: требуются библиотеки lxml и beautifulsoup4
# pip install lxml beautifulsoup4

# Чтение из URL
tables = pd.read_html("https://example.com/table.html")

# Проверить количество найденных таблиц
print(f"Найдено {len(tables)} таблиц")

# Получить первую таблицу
df = tables[0]
print(df.head())

Чтение нескольких таблиц

Веб-страница может содержать несколько таблиц.read_html()Возвращает список, который можно выбрать по индексу:

Пример

import pandas as pd

# Предположим, что веб-страница содержит несколько таблиц
tables = pd.read_html("https://example.com/data.html")

# Перебрать все таблицы
for i, table in enumerate(tables):
    print(f"\n=== Таблица {i+1} ===)
    print(f"Форма: {table.shape}")
    print(table.head(3))

Подробное объяснение общих параметров

Параметр Описание Пример
io Источник входных данных: может быть URL, путь к файлу или строка "page.html"
match Сопоставление по регулярному выражению, фильтрация таблиц, содержащих определённый текст match="销售额"
header Укажите индекс строки заголовка header=0
attrs Фильтруйте таблицы по атрибутам HTML attrs={"id": "table1"}
skiprows Пропустить указанные строки skiprows=[0, 1]
na_values Укажите строки, которые считаются пропущенными значениями na_values=["N/A"]

Используйте параметр match для фильтрации таблиц

Пример

import pandas as pd

# Используйте параметр match, чтобы возвращать только таблицы, содержащие определённый текст
# Например: читать только таблицы, содержащие слово "stock"
tables = pd.read_html(
    "https://example.com/finance.html",
    match="stock"
)

if tables:
    df = tables[0]
    print(df)

Используйте параметр attrs для точного поиска таблиц

Пример

import pandas as pd

# Поиск таблиц по HTML-атрибутам
# Например: получить таблицу с id="stock-table"
tables = pd.read_html(
    "https://example.com/data.html",
    attrs={"id": "stock-table"}  # Найдите элемент таблицы с id="stock-table"
)

# Или найдите по классу
tables = pd.read_html(
    "https://example.com/data.html",
    attrs={"class": "data-table"}
)

df = tables[0]
print(df)

Практический пример: сбор данных об акциях с веб-страницы

Следующий пример демонстрирует, как собрать данные списка акций с финансового веб-сайта:

Пример

import pandas as pd
from io import StringIO


# Создайте тестовое HTML-содержимое для демонстрации
# Замените на реальный URL при фактическом использовании
html_content = '''
<table border="1">
    <tr>
<th>Код акции</th>
<th>Название акции</th>
<th>Цена закрытия</th>
<th>Процент изменения</th>
    </tr>
    <tr>
        <td>600519</td>
<td>Kweichow Moutai</td>
        <td>1850.00</td>
        <td>2.35%</td>
    </tr>
    <tr>
        <td>000858</td>
<td>Wuliangye</td>
        <td>185.50</td>
        <td>-1.20%</td>
    </tr>
    <tr>
        <td>601318</td>
<td>Ping An of China</td>
        <td>52.30</td>
        <td>0.85%</td>
    </tr>
</table>
'''


# Чтение таблицы из строки

tables = pd.read_html(StringIO(html_content))

df = tables[0]

print("Исходная таблица:")
print(df)
print()

# Очистка данных: обработка столбца процентного изменения
df["Change Percent"] = df["Change Percent"].str.replace("%", "").astype(float)
df["Closing Price"] = df["Closing Price"].astype(float)

print("Очищенные данные:")
print(df)

Роль StringIO заключается в том, чтобы замаскировать строку под файловый объект, поэтому pandas обрабатывает её по логике чтения файлового потока, а не принимает её за путь или URL.

Вывод:

原始表格:
     股票代码  股票名称     收盘价     涨跌幅
0  600519  贵州茅台  1850.0   2.35%
1     858   五粮液   185.5  -1.20%
2  601318  中国平安    52.3   0.85%

清洗后的数据:
     股票代码  股票名称     收盘价   涨跌幅
0  600519  贵州茅台  1850.0  2.35
1     858   五粮液   185.5 -1.20
2  601318  中国平安    52.3  0.85

Чтение таблиц Wikipedia

Пример

import pandas as pd

# Чтение таблиц со страницы Wikipedia
# На примере списка стран по населению
url = "https://en.wikipedia.org/wiki/List_of_countries_by_population_(United_Nations)"

try:
    tables = pd.read_html(url)
    print(f"На этой странице всего {len(tables)} таблиц")

    # Обычно первая таблица — это та, которая нам нужна
    df = tables[0]
    print(df.head(10))
except Exception as e:
    print(f"Ошибка чтения: {e}")
    print("Пожалуйста, убедитесь, что необходимые библиотеки установлены: pip install lxml beautifulsoup4")

Очистка и обработка данных

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

Типичные операции очистки

Пример

import pandas as pd
from io import StringIO

# Симуляция таблицы, содержащей различные грязные данные
html_content = '''
<table>
<tr><th>Дата</th><th>Товар</th><th>Продажи</th><th>Примечания</th></tr>
<tr><td>2024-01-01</td><td>Товар A</td><td>1,234</td><td>Н/Д</td></tr>
<tr><td>2024-01-02</td><td>Товар B</td><td>567</td><td>Нет в наличии</td></tr>
<tr><td>2024-01-03</td><td>Товар C</td><td>--</td><td>Не учитывается</td></tr>
</table>
'''


df = pd.read_html(StringIO(html_content))[0]
print("Исходные данные:")
print(df)
print()

# Этапы очистки
# 1. Переименовать столбцы
df.columns = ["Дата", "Товар", "Продажи", "Примечания"]

# 2. Обработать пропущенные значения
df = df.replace(["N/A", "--", "Не учитывается", "Нет в наличии"], pd.NA)

# 3. Очистить числовые столбцы (удалить запятые)
df["Sales"] = df["Sales"].str.replace(",", "").replace(pd.NA, None)
df["Sales"] = pd.to_numeric(df["Sales"], errors="coerce")

# 4. Преобразование дат
df["Date"] = pd.to_datetime(df["Date"])

print("После очистки:")
print(df)
print("\n"Типы данных:")
print(df.dtypes)

Вывод:

原始数据:
           日期   产品    销量   备注
0  2024-01-01  产品A  1234  NaN
1  2024-01-02  产品B   567   缺货
2  2024-01-03  产品C    --  未统计

清洗后:
          日期   产品      销量    备注
0 2024-01-01  产品A  1234.0   NaN
1 2024-01-02  产品B   567.0  <NA>
2 2024-01-03  产品C     NaN  <NA>

数据类型:
日期    datetime64[ns]
产品            object
销量           float64
备注            object
dtype: object

Примечания и типичные проблемы

1. Установка библиотек зависимостей

read_html()Обязательныйlxmlиbeautifulsoup4библиотеки:

pip install lxml beautifulsoup4

2. Проблемы с сетью

При чтении сетевого URL вы можете столкнуться с задержками сети или ограничениями доступа. Рекомендуется добавить соответствующие настройки тайм-аута или использовать локальное кэширование.

3. Сложная структура таблицы

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

4. Целостность данных

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

При сборе данных из интернета соблюдайте правила robots.txt сайта и соответствующие законы и нормативные акты, а также не делайте частых запросов, чтобы не создавать нагрузку на сервер.


Итог

pd.read_html()Это мощный инструмент для сбора данных из веб-таблиц, который быстро преобразует HTML-таблицы в DataFrames. При практическом использовании нужно обращать внимание на установку библиотек зависимостей, решение проблем с сетью, очистку грязных данных и другие вопросы. Собранные данные обычно требуют дополнительной обработки, прежде чем их можно будет использовать для анализа. Рекомендуется использовать его вместе с функциями очистки данных Pandas.

Другие расширения