как из текстового файла извлечь строку с описанием при помощи python?
Имеется текстовый файл, в нём сформирована html-таблица, как вытащить 2 строки с неким описанием и поместить их в столбец в Excel, предварительно их обработав(в них присутствуют теги их нужно убрать)?
В текстовике множество таких строк, строки с описанием написаны кириллицей, остальные строки, либо кракозябры, либо просто теги.Не представляю как это реализовать, заранее спасибо всем тем кто откликнется.
Нашёл вот такой код он удаляет все теги но этого недостаточно, нужно ещё зачистить то что было внутри тегов не считая столбцов Prim и PrimRadio:
import re
f = open('test.txt', 'r').read()
raw_html = f.read()
f.close()
def cleanhtml(raw_html):
cleanr = re.compile('<.*?>|&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});')
cleantext = re.sub(cleanr, '', raw_html)
print(cleantext)
cleanhtml(raw_html)
Ответы (2 шт):
Самым коротким способом будет сделать подобное через Pandas. Решение фактически занимает всего 2 строчки:
import pandas as pd
# Здесь мы считываем данные из файла с html-кодом таблицы
df = pd.read_html(
r'path/to/test.html', # путь до файла с таблицей
header = 1, # номер строки с заголовками (у вас это вторая строка)
encoding='utf-8', # кодировка файла
)[0] # так как функция возвращает список датафреймов, то берем первый результат
# следующая функция сохранит из полученного датафрейма
# все строки по выбранным колонкам (Prim, PrimRadio)
# в файл с расширением xlsx
df[['Prim', 'PrimRadio']].to_excel(
r'path/to/test.xlsx', # путь до файла xlsx
encoding='cp1251', # кодировка. В Windows корректно отображается cp1251
)
Если я правильно понял задачу то приблизительно вот так можно решить через bs4:
# pip install bs4 openpyxl pandas
# Если не установлены
import pandas as pd
from bs4 import BeautifulSoup as Soup
from bs4.element import Tag
if __name__ == '__main__':
with open('test.html', 'r', encoding='utf-8') as html:
soup = Soup(html.read(), 'html.parser')
rows = soup.find_all('tr')
headers_row: Tag
headers_row = rows[1]
headers = {td.text.strip(): num for num, td in enumerate(headers_row.find_all('td'))}
constructor = {h: [] for h in headers}
for row in rows[2:]: # Вот здесь нужно уточнить структуру файла из которого читаем данные
# Тоесть как там располагаются строки относительно друг друга
# Тоесть больше строк нужно для понимания структуры в исходнике
values = [val.text.strip() for val in rows[2].find_all('td')]
for key in constructor:
constructor[key] += [values[headers[key]]]
pd.DataFrame(constructor).to_excel('./test.xlsx', engine='openpyxl', index=False)
На выходе получаем вот такой excel

Если нужны только несколько конкретных столбцов то:
with open('test.html', 'r', encoding='utf-8') as html:
soup = Soup(html.read(), 'html.parser')
rows = soup.find_all('tr')
headers_row: Tag
headers_row = rows[1]
headers = {td.text.strip(): num for num, td in enumerate(headers_row.find_all('td'))}
constructor = {
'Prim': [],
'PrimRadio': []
}
for row in rows[2:]:
values = [val.text.strip() for val in rows[2].find_all('td')]
for key in constructor:
constructor[key] += [values[headers[key]]]
pd.DataFrame(constructor).to_excel('./test.xlsx', engine='openpyxl', index=False, encoding='cp1251')
P.S. Но чисто через
pandasкак здесь уже предложили как мне кажется изящней
UUPD Для большого количества строк
# Время выполнения около 4х минут на 53000 tr
import re
import pandas as pd
from bs4 import BeautifulSoup as Soup
from progressbar import ProgressBar
# прогресс бар для антуражу. установка pip install progressbar2
with open('test.html', 'r', encoding='utf-8') as html:
f = html.read()
iterator = re.finditer(r'<TR>.+?</TR>', f, flags=re.S)
iter_len = len(re.findall(r'<TR>.+?</TR>', f, flags=re.S))
next(iterator)
headers_row = Soup(next(iterator).group(0), 'html.parser')
headers = {td.text.strip(): num for num, td in enumerate(headers_row.find_all('td'))}
constructor = {
'Prim': [],
'PrimRadio': []
}
def get_values(html_tag: str):
soup = Soup(html_tag, 'html.parser')
values = [val.text.strip() for val in soup.find_all('td')]
for key in constructor:
constructor[key] += [values[headers[key]]]
iter_count = 0
with ProgressBar(max_value=iter_len) as bar:
while True:
try:
get_values(next(iterator).group(0))
iter_count += 1
bar.update(iter_count)
except StopIteration:
pd.DataFrame(constructor).to_excel('./test.xlsx', engine='openpyxl', index=False, encoding='cp1251')
break