您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關使用python怎么提取html文本,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
# coding: utf-8 from time import time import warc from bs4 import BeautifulSoup from selectolax.parser import HTMLParser def get_text_bs(html): tree = BeautifulSoup(html, 'lxml') body = tree.body if body is None: return None for tag in body.select('script'): tag.decompose() for tag in body.select('style'): tag.decompose() text = body.get_text(separator='\n') return text def get_text_selectolax(html): tree = HTMLParser(html) if tree.body is None: return None for tag in tree.css('script'): tag.decompose() for tag in tree.css('style'): tag.decompose() text = tree.body.text(separator='\n') return text def read_doc(record, parser=get_text_selectolax): url = record.url text = None if url: payload = record.payload.read() header, html = payload.split(b'\r\n\r\n', maxsplit=1) html = html.strip() if len(html) > 0: text = parser(html) return url, text def process_warc(file_name, parser, limit=10000): warc_file = warc.open(file_name, 'rb') t0 = time() n_documents = 0 for i, record in enumerate(warc_file): url, doc = read_doc(record, parser) if not doc or not url: continue n_documents += 1 if i > limit: break warc_file.close() print('Parser: %s' % parser.__name__) print('Parsing took %s seconds and produced %s documents\n' % (time() - t0, n_documents))
>>> ! wget https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2018-05/segments/1516084886237.6/warc/CC-MAIN-20180116070444-20180116090444-00000.warc.gz >>> file_name = "CC-MAIN-20180116070444-20180116090444-00000.warc.gz" >>> process_warc(file_name, get_text_selectolax, 10000) Parser: get_text_selectolax Parsing took 16.170367002487183 seconds and produced 3317 documents >>> process_warc(file_name, get_text_bs, 10000) Parser: get_text_bs Parsing took 432.6902508735657 seconds and produced 3283 documents
顯然,這并不是對某些事物進行基準測試的最佳方法,但是它提供了一個想法,即selectolax有時比lxml快30倍。
selectolax最適合將HTML剝離為純文本。如果我有10,000多個HTML片段,需要將它們作為純文本索引到Elasticsearch中。(Elasticsearch有一個html_strip文本過濾器,但這不是我想要/不需要在此上下文中使用的過濾器)。事實證明,以這種規模將HTML剝離為純文本實際上是非常低效的。那么,最有效的方法是什么?
PyQuery
from pyquery import PyQuery as pq text = pq(html).text()
selectolax
from selectolax.parser import HTMLParser text = HTMLParser(html).text()
正則表達式
import re regex = re.compile(r'<.*?>') text = clean_regex.sub('', html)
我編寫了一個腳本來計算時間,該腳本遍歷包含HTML片段的10,000個文件。注意!這些片段不是完整的<html>文檔(帶有<head>和<body>等),只是HTML的一小部分。平均大小為10,314字節(中位數為5138字節)。結果如下:
pyquery SUM: 18.61 seconds MEAN: 1.8633 ms MEDIAN: 1.0554 ms selectolax SUM: 3.08 seconds MEAN: 0.3149 ms MEDIAN: 0.1621 ms regex SUM: 1.64 seconds MEAN: 0.1613 ms MEDIAN: 0.0881 ms
我已經運行了很多次,結果非常穩定。重點是:selectolax比PyQuery快7倍。
對于最基本的HTML Blob,它可能工作得很好。實際上,如果HTML是<p> Foo&amp; Bar </ p>,我希望純文本轉換應該是Foo&Bar,而不是Foo&amp; bar。
更重要的一點是,PyQuery和selectolax支持非常特定但對我的用例很重要的內容。在繼續之前,我需要刪除某些標簽(及其內容)。例如:
<h5 class="warning">This should get stripped.</h5> <p>Please keep.</p> <div >This should also get stripped.</div>
正則表達式永遠無法做到這一點。
因此,我的要求可能會發生變化,但基本上,我想刪除某些標簽。例如:<div class =“ warning”> 、 <div class =“ hidden”> 和 <div style =“ display:none”>。因此,讓我們實現一下:
PyQuery
from pyquery import PyQuery as pq _display_none_regex = re.compile(r'display:\s*none') doc = pq(html) doc.remove('div.warning, div.hidden') for div in doc('div[style]').items(): style_value = div.attr('style') if _display_none_regex.search(style_value): div.remove() text = doc.text()
selectolax
from selectolax.parser import HTMLParser _display_none_regex = re.compile(r'display:\s*none') tree = HTMLParser(html) for tag in tree.css('div.warning, div.hidden'): tag.decompose() for tag in tree.css('div[style]'): style_value = tag.attributes['style'] if style_value and _display_none_regex.search(style_value): tag.decompose() text = tree.body.text()
這實際上有效。當我現在為10,000個片段運行相同的基準時,新結果如下:
pyquery SUM: 21.70 seconds MEAN: 2.1701 ms MEDIAN: 1.3989 ms selectolax SUM: 3.59 seconds MEAN: 0.3589 ms MEDIAN: 0.2184 ms regex Skip
上述就是小編為大家分享的使用python怎么提取html文本了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。