假设我们需要从各种网页中提取全文,并且要剥离所有HTML标记。通常,默认解决方案是使用BeautifulSoup软件包中的get_text方法,该方法内部使用lxml。这是一个经过充分测试的解决方案,但是在处理成千上万个HTML文档时可能会非常慢。

通过用selectolax替换BeautifulSoup,您几乎可以免费获得5-30倍的加速!

这是一个简单的基准测试,可分析commoncrawl(`处理NLP问题时,有时您需要获得大量的文本集。互联网是文本的最大来源,但是不幸的是,从任意HTML页面提取文本是一项艰巨而痛苦的任务。

假设我们需要从各种网页中提取全文,并且要剥离所有HTML标记。通常,默认解决方案是使用BeautifulSoup软件包中的get_text方法,该方法内部使用lxml。这是一个经过充分测试的解决方案,但是在处理成千上万个HTML文档时可能会非常慢。

通过用selectolax替换BeautifulSoup,您几乎可以免费获得5-30倍的加速!这是一个简单的基准测试,可分析commoncrawl(https://commoncrawl.org/)的10,000个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的一小部分。平均大小为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是

Foo&amp; Bar p>,我希望纯文本转换应该是Foo&Bar,而不是Foo&amp; bar。

更重要的一点是,PyQuery和selectolax支持非常特定但对我的用例很重要的内容。在继续之前,我需要删除某些标签(及其内容)。例如:

This should get stripped.

Please keep.

This should also get stripped.

正则表达式永远无法做到这一点。

2.0 版本

因此,我的要求可能会发生变化,但基本上,我想删除某些标签。例如:

。因此,让我们实现一下:

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

同样,selectolax击败PyQuery约6倍。

结论

正则表达式速度快,但功能弱。selectolax的效率令人印象深刻。

以上就是python 提取html文本的方法的详细内容,更多关于python 提取html文本的资料请关注脚本之家其它相关文章!

python提取html正文为txt,python 提取html文本的方法相关推荐

  1. python 提取网页正文_用Python写个爬虫小程序,给女朋友每日定时推送睡前小故事...

    ↑ 关注 + 星标 ,每天学Python新技能后台回复[大礼包]送你Python自学大礼 导读:这篇文章利用简单的Python爬虫.邮件发送以及定时任务实现了每天定时发送睡前小故事的功能,是一篇步骤详 ...

  2. 使用PYTHON将上百个TXT文件提取其中信息生成一个csv

    原文件目录如图 只把他们合并成一个txt没到到自己的需要,我需要做成一个如图所示的csv文件,以上传服务器生成文章 上代码: #coded by伊玛目的门徒 多个txt提取关键信息生成csv #cod ...

  3. 【Python】matplotlib可视化必知必会富文本绘制方法

    ❝ 本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes ❞ 1 简介 长久以来,在使用matplotli ...

  4. python3性能还低吗_谁说Python性能差的?-- 让python比awk快 (3)

    在(2)中,提到了python字符串慢在了split函数.那既然已经知道这个bottleneck,现在就优化下. 初步思路是用C来定制一个提取第n列数的模块,然后替换我们的Python版本(1)中的s ...

  5. linux如何提取文件名称,Linux shell 之 提取文件名和目录名的一些方法总结

    很多时候在使用Linux的shell时,我们都需要对文件名或目录名进行处理,通常的操作是由路径中提取出文件名,从路径中提取出目录名,提取文件后缀名等等.例如,从路径/dir1/dir2/file.tx ...

  6. Python 提取网页正文,将网页转为图片!

    Python 提取网页正文,将网页转为图片!!! 用到python的newspaper库 from newspaper import Article news = Article(link.strip ...

  7. python 提取网页正文_小苹果来科普 | 关于python爬虫的那些事儿

    python爬虫--抓取小说 爬虫=Python? 网络爬虫是什么? 不好意思,这些网上查的到的东西我不愿意打字啊,请移步百度百科-- 使用python抓取网页信息少不了一些有关html的知识 首先要 ...

  8. python提取列表中文本_python提取图像的名字*.jpg到txt文本的方法

    如下所示: # -*- coding:utf-8 -*- import sys sys.path.append('E:\\Anaconda\\libs') import os #os:操作系统相关的信 ...

  9. python获取图片名称_python提取图像的名字*.jpg到txt文本的方法

    如下所示: # -*- coding:utf-8 -*- import sys sys.path.append('E:\\Anaconda\\libs') import os #os:操作系统相关的信 ...

最新文章

  1. SpringMVC+MyBatis+Druid使用MySQL8.0.11版本
  2. html html示例
  3. logstash mysql日期_logstash-input-jdbc取mysql数据日期格式处理
  4. python知识:稀疏矩阵转换成密度矩阵
  5. C#抽象类与密封类-abstract-sealed
  6. Flutter获取随机数 Dart语言核心基础
  7. Confluence 6 理解你许可证的用户数
  8. 修改mongodb最大查询数_mongodb数据库如何查询某个字段的最大值?
  9. 斗鱼第三方开放平台2.2版使用记录
  10. 自然语言处理——TF-IDF文本表示
  11. caxa自动保存的文件在哪里_怎样删除CAXA的临时文件
  12. T1-商贸宝 将辅助单位零售价更新为基本单位零售价*换算率
  13. 线性方程组(四)- 矩阵方程
  14. 使用Service Worker发送Push推送
  15. 什么样的面试更有效?
  16. 第九篇:万丈高楼平地起-驱动编程基础知识点
  17. Activiti,自定义表单,外置表单,工作流,微服务,子系统
  18. linux 怎么烧录光盘,Linux下的光盘烧录工具brasero
  19. 微信h5小游戏作品欣赏:详解微信h5如何制作
  20. linux+zip+加密+无交互,Linux下zip加密压缩

热门文章

  1. Spring @Order批注
  2. q7goodies事例_Java 8 Friday Goodies:本地交易范围
  3. jvm破坏双亲委派_破坏JVM
  4. eclipse 隐藏项目_前5个有用的隐藏Eclipse功能
  5. kryo java_优化Java序列化– Java,XML,JSON,Kryo,POF
  6. JBoss Fuse:使用JEXL的动态蓝图文件
  7. 扩展Java EE应用程序的基础
  8. jboss7.0.2_JBoss AS 7.0.2“ Arc”发布–使用绑定选项
  9. 使用JAX-RS和Jetty创建Web服务和Rest Server
  10. Java旧版不断发展