佳木斯湛栽影视文化发展公司

主頁 > 知識(shí)庫 > python 提取html文本的方法

python 提取html文本的方法

熱門標(biāo)簽:硅谷的囚徒呼叫中心 企業(yè)做大做強(qiáng) 電話運(yùn)營中心 語音系統(tǒng) 呼叫中心市場(chǎng)需求 客戶服務(wù) Win7旗艦版 百度AI接口

假設(shè)我們需要從各種網(wǎng)頁中提取全文,并且要?jiǎng)冸x所有HTML標(biāo)記。通常,默認(rèn)解決方案是使用BeautifulSoup軟件包中的get_text方法,該方法內(nèi)部使用lxml。這是一個(gè)經(jīng)過充分測(cè)試的解決方案,但是在處理成千上萬個(gè)HTML文檔時(shí)可能會(huì)非常慢。
通過用selectolax替換BeautifulSoup,您幾乎可以免費(fèi)獲得5-30倍的加速!
這是一個(gè)簡(jiǎn)單的基準(zhǔn)測(cè)試,可分析commoncrawl(`處理NLP問題時(shí),有時(shí)您需要獲得大量的文本集?;ヂ?lián)網(wǎng)是文本的最大來源,但是不幸的是,從任意HTML頁面提取文本是一項(xiàng)艱巨而痛苦的任務(wù)。
假設(shè)我們需要從各種網(wǎng)頁中提取全文,并且要?jiǎng)冸x所有HTML標(biāo)記。通常,默認(rèn)解決方案是使用BeautifulSoup軟件包中的get_text方法,該方法內(nèi)部使用lxml。這是一個(gè)經(jīng)過充分測(cè)試的解決方案,但是在處理成千上萬個(gè)HTML文檔時(shí)可能會(huì)非常慢。
通過用selectolax替換BeautifulSoup,您幾乎可以免費(fèi)獲得5-30倍的加速!這是一個(gè)簡(jiǎn)單的基準(zhǔn)測(cè)試,可分析commoncrawl(https://commoncrawl.org/)的10,000個(gè)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

顯然,這并不是對(duì)某些事物進(jìn)行基準(zhǔn)測(cè)試的最佳方法,但是它提供了一個(gè)想法,即selectolax有時(shí)比lxml快30倍。
selectolax最適合將HTML剝離為純文本。如果我有10,000多個(gè)HTML片段,需要將它們作為純文本索引到Elasticsearch中。(Elasticsearch有一個(gè)html_strip文本過濾器,但這不是我想要/不需要在此上下文中使用的過濾器)。事實(shí)證明,以這種規(guī)模將HTML剝離為純文本實(shí)際上是非常低效的。那么,最有效的方法是什么?

  • PyQuery
from pyquery import PyQuery as pq

text = pq(html).text()
  • selectolax
from selectolax.parser import HTMLParser

text = HTMLParser(html).text()
  • 正則表達(dá)式
import re

regex = re.compile(r'.*?>')
text = clean_regex.sub('', html)

結(jié)果

我編寫了一個(gè)腳本來計(jì)算時(shí)間,該腳本遍歷包含HTML片段的10,000個(gè)文件。注意!這些片段不是完整的html>文檔(帶有head>和body>等),只是HTML的一小部分。平均大小為10,314字節(jié)(中位數(shù)為5138字節(jié))。結(jié)果如下:

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

我已經(jīng)運(yùn)行了很多次,結(jié)果非常穩(wěn)定。重點(diǎn)是:selectolax比PyQuery快7倍。

正則表達(dá)式好用?真的嗎?

對(duì)于最基本的HTML Blob,它可能工作得很好。實(shí)際上,如果HTML是p> Foo& Bar / p>,我希望純文本轉(zhuǎn)換應(yīng)該是Foo&Bar,而不是Foo& bar。
更重要的一點(diǎn)是,PyQuery和selectolax支持非常特定但對(duì)我的用例很重要的內(nèi)容。在繼續(xù)之前,我需要?jiǎng)h除某些標(biāo)簽(及其內(nèi)容)。例如:

h4 class="warning">This should get stripped./h4>
p>Please keep./p>
div style="display: none">This should also get stripped./div>

正則表達(dá)式永遠(yuǎn)無法做到這一點(diǎn)。

2.0 版本

因此,我的要求可能會(huì)發(fā)生變化,但基本上,我想刪除某些標(biāo)簽。例如:div class =“ warning”>  、 div class =“ hidden”> 和 div style =“ display:none”>。因此,讓我們實(shí)現(xiàn)一下:

  • 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()

這實(shí)際上有效。當(dāng)我現(xiàn)在為10,000個(gè)片段運(yùn)行相同的基準(zhǔn)時(shí),新結(jié)果如下:

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

同樣,selectolax擊敗PyQuery約6倍。

結(jié)論

正則表達(dá)式速度快,但功能弱。selectolax的效率令人印象深刻。

以上就是python 提取html文本的方法的詳細(xì)內(nèi)容,更多關(guān)于python 提取html文本的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • Python識(shí)別html主要文本框過程解析
  • Python使用get_text()方法從大段html中提取文本的實(shí)例
  • python爬蟲入門教程--HTML文本的解析庫BeautifulSoup(四)
  • Python轉(zhuǎn)換HTML到Text純文本的方法
  • python如何發(fā)送帶有附件、正文為HTML的郵件
  • python中HTMLParser模塊知識(shí)點(diǎn)總結(jié)
  • python郵件中附加文字、html、圖片、附件實(shí)現(xiàn)方法
  • python 將html轉(zhuǎn)換為pdf的幾種方法
  • python爬蟲beautifulsoup解析html方法
  • python爬蟲 requests-html的使用
  • 關(guān)于pycharm 切換 python3.9 報(bào)錯(cuò) ‘HTMLParser‘ object has no attribute ‘unescape‘ 的問題
  • Python HTMLTestRunner如何下載生成報(bào)告

標(biāo)簽:崇左 喀什 長沙 安康 山西 海南 山西 濟(jì)南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《python 提取html文本的方法》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    固始县| 中宁县| 仙桃市| 乌拉特中旗| 永顺县| 息烽县| 高青县| 肇庆市| 平邑县| 大丰市| 汾阳市| 马公市| 乌什县| 松滋市| 津南区| 林口县| 天峻县| 赞皇县| 保山市| 贺州市| 神木县| 姚安县| 青铜峡市| 石狮市| 广汉市| 教育| 陇西县| 晋宁县| 中江县| 新建县| 德惠市| 尤溪县| 稷山县| 天全县| 宜黄县| 福州市| 喀什市| 太湖县| 会东县| 垣曲县| 朝阳市|