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

#python #parsing #web-scraping #beautifulsoup

Вопрос:

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

К сожалению, разбор тех, кто использует BS, и преобразование их в df с использованием df = pd.read_html(str(CompTab)) приводят к беспорядку, так как разрывы строк не учитываются, как вы можете видеть здесь: Иллюстрация

Здесь вы можете увидеть одну из ячеек в столбце «Финансовые годы» с ее html-кодом: HTML-код

После бега:

 resp = requests.get(url_to_use, headers=headers)
soup = bs.BeautifulSoup(resp.text, "html.parser")
    tables = soup.find_all("table")
    #Select the correct table
    for table in tables:
            if ('Name' in str(table)) and ('Year' in str(table)) and ('Salary' in str(table)):
                CompTab = table
    print(CompTab.prettify())
 

…и при поиске html-кода в столбце «Финансовые годы» кажется, что в то время как BS не игнорирует
html-теги, а преобразует их в <br/> теги:

 #Partial Output of print(CompTab.prettify())
<td valign="top">
   <font face="Times New Roman" size="2">
    2006
    <br/>
    2005
    <br/>
    2004
   </font>
  </td>
 

Вместо этого я попытался использовать синтаксический анализатор lxml и даже заменил <br/> теги на <br> . И то, и другое не возымело никакого эффекта.
Как мне получить вывод, учитывающий разрывы строк в том виде, в каком они встречаются в исходной таблице?

Комментарии:

1. исходная таблица деформирована, beautifulsoup здесь ни в чем не виноват. так или иначе, вам придется изменить его

Ответ №1:

Стол, возможно, похоронен где-то в https://www.sec.gov/os/accessing-edgar-data. В любом случае…

введите описание изображения здесь

Так…

Может быть:

 import pandas as pd
import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.3"
}

url = 'https://www.sec.gov/Archives/edgar/data/0001000230/000119312507035211/ddef14a.htm'

page = requests.get(url, headers=headers)
tables = pd.read_html(page.text.replace('<BR>','n'))

df = pd.DataFrame(tables[50])

# df.columns = pd.MultiIndex.from_arrays([df.iloc[1],df.iloc[2]])
# line above or the line below - pick one, comment the other out
df.columns = df.iloc[2]

df = df.iloc[3:]
df = df.reset_index(drop=True)

df = df.dropna(axis=1)

df = df.loc[:,~(df=='

Выход:

введите описание изображения здесь

Поставляющий:

 from styleframe import StyleFrame
StyleFrame(df).to_excel('out.xlsx').save()
 

введите описание изображения здесь

Похоже, что в этих квадратах есть какие x97 -то символы, которые вы, очевидно, можете удалить при очистке.


).any()]

display(df)
Выход:

введите описание изображения здесь

Поставляющий:


введите описание изображения здесь

Похоже, что в этих квадратах есть какие x97 -то символы, которые вы, очевидно, можете удалить при очистке.