В настоящее время у меня есть две функции для извлечения текста HTML <body>
из Python и возврата его в виде набора слов. Они дают эквивалентный результат. Я также очищаю различные теги, которые в противном случае давали бы мне мусорный текст (например, код <script>
).
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, но он не всегда правильно извлекает тело.)