В настоящее время у меня есть две функции для извлечения HTML-кода <body>
из Python и возврата его в виде пакета слов. Они дают эквивалентную мощность. Я также очищаю различные теги, которые в противном случае давали бы мне мусорный текст (например, код <script>
).Каков самый быстрый, самый безошибочный способ извлечения и очистки основного текста HTML в Python?
def html_to_bow_bs(text):
if text is None or len(text)==0:
return []
soup = BeautifulSoup(text, "lxml",parse_only=SoupStrainer('body'))
# Remove all irrelevant tags
for elem in soup.findAll(['script','style','a']):
elem.extract()
body_text = soup.findAll("body")
if len(body_text) == 0:
return []
# Encoding. Remove extra whitespace and unprintable characters
the_text = body_text[0].get_text().encode('utf-8')
the_text = str(the_text)
the_text = the_text.strip()
the_text = re.sub(r'[^\x00-\x7F]+',' ',the_text)
return [w.lower() for w in the_text.split()]
def html_to_bow_bs_lxml(text):
if text is None or len(text)==0:
return []
body_re = re.findall('<body(.*?)</body>', text, flags=re.DOTALL)
if len(body_re) == 0:
return []
fragment = body_re[0]
# Remove irrelevant tags
fragment = re.sub(r'<script.*?</script>', ' ', fragment, flags=re.DOTALL)
fragment = re.sub(r'<style.*?</style>', ' ', fragment, flags=re.DOTALL)
text = "<body" + fragment + "</body>"
soup = BeautifulSoup(text, "lxml")
if soup is None:
return []
# Remote more irrelevant tags
for elem in soup.findAll(['a']):
elem.extract()
# Encoding. Remove extra whitespace and unprintable characters
the_text = body_text[0].get_text().encode('utf-8')
the_text = str(the_text)
the_text = the_text.strip()
the_text = re.sub(r'[^\x00-\x7F]+',' ',the_text)
return [w.lower() for w in the_text.split()]
Мой Главное требование является соответствие вывод: что множество слов из html_to_bow_bs_lxml(text)
матчей html_to_bow_bs(text)
. В настоящее время оба находятся на одном уровне с временем выполнения; для 330 страниц, они работают около 20 секунд (медленно!). Если я удалю и замените свой последний soup.findAll(['a'])...extract()
в моей второй функции с помощью регулярных выражений, я могу сбрить 6 секунд с моего времени. Замена BeautifulSoup
в целом с помощью lxml.etree
может сбрить дополнительные 10 секунд, делая общее время работы около 3-4 секунд. Однако при замене с помощью регулярных выражений
- вывод не всегда совпадает. При замене
BeautifulSoup
либо выход не соответствует, либо - моя программа вылетает во время обработки из-за плохо сформированного HTML. Как увеличить скорость при сохранении правильности?
Я видел различные рекомендации по извлечению HTML с Python, как правило, в StackOverflow, но это датируется несколькими годами (например, 2012 год). С тех пор, по понятным причинам, было много обновлений для библиотек.
(Я также попытался pyquery, но это не всегда извлечь тело правильно.)
Спасибо! Похоже, что были некоторые дополнительные улучшения. Однако 'body.get_text (strip = True)' дал намного меньше слов, чем разделение 'get_text()' и 'strip()' на две разные функции. Я заменил это на «.» .join ([текст для текста в body.stripped_strings]). Encode ('utf-8') 'дает больше слов, которые были фактически упущены моими подходами. Это редактирование, наряду с вышеизложенным, дает почти равную производительность во время выполнения. – Matt
@Matt да, спасибо, я не ожидал значительного повышения производительности от этих изменений. А как насчет пипы? – alecxe
Теперь, попробуйте сейчас. Извините, у меня закончилось свободное пространство комментариев. :) – Matt