从HTML文件中提取正文的简单方案

摘要:
源URL:http://blog.csdn.net/zvane/archive/2008/03/21/2201414.aspx2、基于标记密度判断译者指南:本文主要介绍一种广泛适用的方法,从不同类型的HTML文件中提取真正有用的文本内容。如果您不想为每种类型的HTML文件编写复杂的提取程序,我有一个解决方案。本文描述了如何编写一个简单的脚本来从大量HTML代码中获取正文内容。此方法不需要知道HTML文件的结构和使用的标记。
http://www.basesnet.com/seo/53从HTML文件中提取正文的简单方案
2012-03-07/SEO/HTML文件,提取正文,简单方案/
1
多种基于html正文提取的思想

一、基于统计的中文网页正文抽取的研究

摘要:信息抽取技术是一种广泛运用于互联网的数据挖掘技术。其目的是从互联网海量数据中抽取有意义、有价值的数据和信息,从而能更好的利用互联网资源。文中采用一种统计网页特征的方法,将中文网页中的正文部分抽取出来。该方法首先将网页表示成基于XML的DOM树形式,利用统计的节点信息从树中过滤掉噪音数据节点,最后再选取正文节点。该方法相比传统的基于包装器的抽取方法,具有简单,实用的特点,试验结果表明,该抽取方法准确率达到90%以上,具有很好的实用价值。

来源网址:http://blog.csdn.net/zvane/archive/2008/03/21/2201414.aspx

二、基于标签密度判定

译者导读:这篇文章主要介绍了从不同类型的HTML文件中抽取出真正有用的正文内容的一种有广泛适应性的方法。其功能类似于CSDN近期推出的“剪影”,能够去除页眉、页脚和侧边栏的无关内容,非常实用。其方法简单有效而又出乎意料,看完后难免大呼原来还可以这样!行文简明易懂,虽然应用了人工神经网络这样的算法,但因为FANN良好的封装性,并不要求读者需要懂得ANN。全文示例以Python代码写成,可读性更佳,具有科普气息,值得一读。

每个人手中都可能有一大堆讨论不同话题的HTML文档。但你真正感兴趣的内容可能隐藏于广告、布局表格或格式标记以及无数链接当中。甚至更糟的是,你希望那些来自菜单、页眉和页脚的文本能够被过滤掉。如果你不想为每种类型的HTML文件分别编写复杂的抽取程序的话,我这里有一个解决方案。
本文讲述如何编写与从大量HTML代码中获取正文内容的简单脚本,这一方法无需知道HTML文件的结构和使用的标签。它能够工作于含有文本内容的所有新闻文章和博客页面……
你想知道统计学和机器学习在挖掘文本方面能够让你省时省力的原因吗?
答案极其简单:使用文本和HTML代码的密度来决定一行文件是否应该输出。(这听起来有点离奇,但它的确有用!)基本的处理工作如下:
一、解析HTML代码并记下处理的字节数。
二、以行或段的形式保存解析输出的文本。
三、统计每一行文本相应的HTML代码的字节数
四、通过计算文本相对于字节数的比率来获取文本密度
五、最后用神经网络来决定这一行是不是正文的一部分。
仅仅通过判断行密度是否高于一个固定的阈值(或者就使用平均值)你就可以获得非常好的结果。但你也可以使用机器学习(这易于实现,简直不值一提)来减少这个系统出现的错误。
来源网址:http://hi.baidu.com/whitecpf/blog/item/6c4dffde6004755094ee37c9.html

三、基于数据挖掘思想的网页正文抽取方法的研究

提出了一种依靠数据挖掘思想,从中文新闻类网页中抽取正文内容的方法。该方法将网页源代码进行线性化重构,然后利用重构后的代码进行网页噪声的初步去除,再经过文本分类、聚类得到网页正文的脉络段落,最后通过吸收伪噪声段落生成网页正文。该方法克服了传统的网页内容抽取方法需要为网页结构建树的缺点,具有简单、快速、准确的特点,试验表明该方法的抽取准确率可以达到99%以上。

来源网址:http://epub.cnki.net/grid2008/detail.aspx?filename=ZGZR200608001051&dbname=cpfd2006

四、基于视觉网页块分析技术的正文抽取

基于视觉的正文抽取和网页块分析是完全模拟IE浏览器的显示方式,对网页进行解析。系统根据人类视觉原理,把网页解析处理的结果,进行分块。然后根据用户需求,提取用户需要的提取相关网页块的内容。
比如在竞争情报系统和自动新闻已经采编发系统中,正文的提取。提取:标题、正文、时间等信息。

评:类似根据模板定义去提取网页正文

继续收集中

当然还有很多如通过正则表达式,或剔除html标签等等方式提取正文,但个人认为通用效果不理想。

The Easy Way to Extract Useful Text from Arbitrary HTML
从HTML文件中抽取正文的简单方案
作者:alexjc
原文地址:http://ai-depot.com/articles/the-easy-way-to-extract-useful-text-from-arbitrary-html/
译者导读:这篇文章主要介绍了从不同类型的HTML文件中抽取出真正有用的正文内容的一种有广泛适应性的方法。其功能类似于CSDN近期推出的“剪影”,能够去除页眉、页脚和侧边栏的无关内容,非常实用。其方法简单有效而又出乎意料,看完后难免大呼原来还可以这样!行文简明易懂,虽然应用了人工神经网络这样的算法,但因为FANN良好的封装性,并不要求读者需要懂得ANN。全文示例以Python代码写成,可读性更佳,具有科普气息,值得一读。
You’ve finally got your hands on the diverse collection of HTML documents you needed. But the content you’re interested in is hidden amidst adverts, layout tables or formatting markup, and other various links. Even worse, there’s visible text in the menus, headers and footers that you want to filter out. If you don’t want to write a complex scraping program for each type of HTML file, there is a solution.
每个人手中都可能有一大堆讨论不同话题的HTML文档。但你真正感兴趣的内容可能隐藏于广告、布局表格或格式标记以及无数链接当中。甚至更糟的是,你希望那些来自菜单、页眉和页脚的文本能够被过滤掉。如果你不想为每种类型的HTML文件分别编写复杂的抽取程序的话,我这里有一个解决方案。
This article shows you how to write a relatively simple script to extract text paragraphs from large chunks of HTML code, without knowing its structure or the tags used. It works on news articles and blogs pages with worthwhile text content, among others…
本文讲述如何编写与从大量HTML代码中获取正文内容的简单脚本,这一方法无需知道HTML文件的结构和使用的标签。它能够工作于含有文本内容的所有新闻文章和博客页面……
Do you want to find out how statistics and machine learning can save you time and effort mining text?
你想知道统计学和机器学习在挖掘文本方面能够让你省时省力的原因吗?

< type=text/javascript>The concept is rather simple: use information about the density of text vs. HTML code to work out if a line of text is worth outputting. (This isn’t a novel idea, but it works!) The basic process works as follows:

答案极其简单:使用文本和HTML代码的密度来决定一行文件是否应该输出。(这听起来有点离奇,但它的确有用!)基本的处理工作如下:
  1. Parse the HTML code and keep track of the number of bytes processed.
一、解析HTML代码并记下处理的字节数。
  1. Store the text output on a per-line, or per-paragraph basis.
二、以行或段的形式保存解析输出的文本。
  1. Associate with each text line the number of bytes of HTML required to describe it.
三、统计每一行文本相应的HTML代码的字节数
  1. Compute the text density of each line by calculating the ratio of text to bytes.
四、通过计算文本相对于字节数的比率来获取文本密度
  1. Then decide if the line is part of the content by using a neural network.
五、最后用神经网络来决定这一行是不是正文的一部分。
You can get pretty good results just by checking if the line’s density is above a fixed threshold (or the average), but the system makes fewer mistakes if you use machine learning — not to mention that it’s easier to implement!
仅仅通过判断行密度是否高于一个固定的阈值(或者就使用平均值)你就可以获得非常好的结果。但你也可以使用机器学习(这易于实现,简直不值一提)来减少这个系统出现的错误。
Let’s take it from the top…
现在让我从头开始……
Converting the HTML to Text
转换HTML为文本
What you need is the core of a text-mode browser, which is already setup to read files with HTML markup and display raw text. By reusing existing code, you won’t have to spend too much time handling invalid XML documents, which are very common — as you’ll realise quickly.
你需要一个文本模式浏览器的核心,它应该已经内建了读取HTML文件和显示原始文本功能。通过重用已有代码,你并不需要把很多时间花在处理无效的XML文件上。
As a quick example, we’ll be usingPythonalong with a few built-in modules: htmllib for the parsing and formatter for outputting formatted text. This is what the top-level function looks like:
我们将使用Python来完成这个例子,它的htmllib模块可用以解析HTML文件,formatter模块可用以输出格式化的文本。嗯,实现的顶层函数如下:
defextract_text(html):
# Derive from formatter.AbstractWriter to store paragraphs.
writer = LineWriter()
# Default formatter sends commands to our writer.
formatter= AbstractFormatter(writer)
# Derive from htmllib.HTMLParser to track parsed bytes.
parser= TrackingParser(writer,formatter)
# Give the parser the raw HTML data.
parser.feed(html)
parser.close()
# Filter the paragraphs stored and output them.
returnwriter.output()
The TrackingParser itself overrides the callback functions for parsing start and end tags, as they are given the current parse index in the buffer. You don’t have access to that normally, unless you start diving into frames in the call stack — which isn’t the best approach! Here’s what the class looks like:
TrackingParser覆盖了解析标签开始和结束时调用的回调函数,用以给缓冲对象传递当前解析的索引。通常你不得不这样,除非你使用不被推荐的方法——深入调用堆栈去获取执行帧。这个类看起来是这样的:
classTrackingParser(htmllib.HTMLParser):
”"”Try to keep accurate pointer of parsing location.”"”
def__init__(self, writer, *args):
htmllib.HTMLParser.__init__(self, *args)
self.writer= writer
defparse_starttag(self, i):
index =htmllib.HTMLParser.parse_starttag(self, i)
self.writer.index= index
returnindex
defparse_endtag(self, i):
self.writer.index= i
returnhtmllib.HTMLParser.parse_endtag(self, i)
The LineWriter class does the bulk of the work when called by the default formatter. If you have any improvements or changes to make, most likely they’ll go here. This is where we’ll put our machine learning code in later. But you can keep the implementation rather simple and still get good results. Here’s the simplest possible code:
LinWriter的大部分工作都通过调用formatter来完成。如果你要改进或者修改程序,大部分时候其实就是在修改它。我们将在后面讲述怎么为它加上机器学习代码。但你也可以保持它的简单实现,仍然可以得到一个好结果。具体的代码如下:
classParagraph:
def__init__(self):
self.text=”
self.bytes=0
self.density=0.0
classLineWriter(formatter.AbstractWriter):
def__init__(self, *args):
self.last_index=0
self.lines=[Paragraph()]
formatter.AbstractWriter.__init__(self)
defsend_flowing_data(self, data):
# Work out the length of this text chunk.
t =len(data)
# We’ve parsed more text, so increment index.
self.index+= t
# Calculate the number of bytes since last time.
b =self.index-self.last_index
self.last_index=self.index
# Accumulate this information in current line.
l =self.lines[-1]
l.text+= data
l.bytes+= b
defsend_paragraph(self, blankline):
”"”Create a new paragraph if necessary.”"”
ifself.lines[-1].text==”:
return
self.lines[-1].text+=’n'*(blankline+1)
self.lines[-1].bytes+=2*(blankline+1)
self.lines.append(Writer.Paragraph())
defsend_literal_data(self, data):
self.send_flowing_data(data)
defsend_line_break(self):
self.send_paragraph(0)
This code doesn’t do any outputting yet, it just gathers the data. We now have a bunch of paragraphs in an array, we know their length, and we know roughly how many bytes of HTML were necessary to create them. Let’s see what emerge from our statistics.
这里代码还没有做输出部分,它只是聚合数据。现在我们有一系列的文字段(用数组保存),以及它们的长度和生成它们所需要的HTML的大概字节数。现在让我们来看看统计学带来了什么。
Examining the Data
数据分析
Luckily, there are some patterns in the data. In the raw output below, you’ll notice there are definite spikes in the number of HTML bytes required to encode lines of text, notably around the title, both sidebars, headers and footers.
幸运的是,数据里总是存在一些模式。从下面的原始输出你可以发现有些文本需要大量的HTML来编码,特别是标题、侧边栏、页眉和页脚。
从HTML文件中提取正文的简单方案第1张
While the number of HTML bytes spikes in places, it remains below average for quite a few lines. On these lines, the text output is rather high. Calculating the density of text to HTML bytes gives us a better understanding of this relationship.
虽然HTML字节数的峰值多次出现,但大部分仍然低于平均值;我们也可以看到在大部分低HTML字节数的字段中,文本输出却相当高。通过计算文本与HTML字节数的比率(即密度)可以让我们更容易明白它们之间的关系:
从HTML文件中提取正文的简单方案第2张
The patterns are more obvious in this density value, so it gives us something concrete to work with.
密度值图更加清晰地表达了正文的密度更高,这是我们的工作的事实依据。
Filtering the Lines
过滤文本行
The simplest way we can filter lines now is by comparing the density to a fixed threshold, such as 50% or the average density. Finishing the LineWriter class:
过滤文本行的最简单方法是通过与一个阈值(如50%或者平均值)比较密度值。下面来完成LineWriter类:
defcompute_density(self):
”"”Calculate the density for each line, and the average.”"”
total =0.0
forlinself.lines:
l.density=len(l.text)/float(l.bytes)
total += l.density
# Store for optional use by the neural network.
self.average= total /float(len(self.lines))
defoutput(self):
”"”Return a string with the useless lines filtered out.”"”
self.compute_density()
output =StringIO.StringIO()
forlinself.lines:
# Check density against threshold.
# Custom filter extensions go here.
ifl.density>0.5:
output.write(l.text)
returnoutput.getvalue()
This rough filter typically gets most of the lines right. All the headers, footers and sidebars text is usually stripped as long as it’s not too long. However, if there are long copyright notices, comments, or descriptions of other stories, then those are output too. Also, if there are short lines around inline graphics or adverts within the text, these are not output.
这个粗糙的过滤器能够获取大部分正确的文本行。只要页眉、页脚和侧边栏文本并不非常长,那么所有的这些都会被剔除。然而,它仍然会输出比较长的版本声明、注释和对其它故事的概述;在图片和广告周边的比较短小的文本,却被过滤掉了。
To fix this, we need a more complex filtering heuristic. But instead of spending days working out the logic manually, we’ll just grab loads of information about each line and use machine learning to find patterns for us.
要解决这个问题,我们需要更复杂些的启发式过滤器。为了节省手工计算需要花费的无数时间,我们将利用机器学习来处理每一文本行的信息,以找出对我们有用的模式。
Supervised Machine Learning
监督式机器学习
Here’s an example of an interface for tagging lines of text as content or not:
这是一个标识文本行是否为正文的接口界面:
从HTML文件中提取正文的简单方案第3张
The idea of supervised learning is to provide examples for an algorithm to learn from. In our case, we give it a set documents that were tagged by humans, so we know which line must be output and which line must be filtered out. For this we’ll use a simple neural network known as the perceptron. It takes floating point inputs and filters the information through weighted connections between “neurons” and outputs another floating point number. Roughly speaking, the number of neurons and layers affects the ability to approximate functions precisely; we’ll use both single-layer perceptrons (SLP) and multi-layer perceptrons (MLP) for prototyping.
所谓的监督式学习就是为算法提供学习的例子。在这个案例中,我们给定一系列已经由人标识好的文档——我们知道哪一行必须输出或者过滤掉。我们用使用一个简单的神经网络作为感知器,它接受浮点输入并通过“神经元”间的加权连接过滤信息,然后输后另一个浮点数。大体来说,神经元数量和层数将影响获取最优解的能力。我们的原型将分别使用单层感知器(SLP)和多层感知器(MLP)模型。
To get the neural network to learn, we need to gather some data. This is where the earlier LineWriter.output() function comes in handy; it gives us a central point to process all the lines at once, and make a global decision which lines to output. Starting with intuition and experimenting a bit, we discover that the following data is useful to decide how to filter a line:
我们需要找些数据来供机器学习。之前的LineWriter.output()函数正好派上用场,它使我们能够一次处理所有文本行并作出决定哪些文本行应该输出的全局结策。从直觉和经验中我们发现下面的几条原则可用于决定如何过滤文本行:
  • Density of thecurrentline.
  • 当前行的密度
  • Number of HTML bytes of the line.
  • 当前行的HTML字节数
  • Length of output text for this line.
  • 当前行的输出文本长度
  • These three values for the previous line,
  • 前一行的这三个值
  • … and the same for the next line.
  • 后一行的这三个值
For the implementation, we’ll be using Python to interface with FANN, the Fast Artificial Neural Network Library. The essence of the learning code goes like this:
我们可以利用FANN的Python接口来实现,FANN是Fast Artificial Neural NetWork库的简称。基本的学习代码如下:
frompyfannimportfann, libfann
# This creates a new single-layer perceptron with 1 output and 3 inputs.
obj = libfann.fann_create_standard_array(2,(3,1))
ann = fann.fann_class(obj)
# Load the data we described above.
patterns = fann.read_train_from_file(‘training.txt’)
ann.train_on_data(patterns,1000,1,0.0)
# Then test it with different data.
fordatin, datoutinvalidation_data:
result = ann.run(datin)
print’Got:’, result,’ Expected:’, datout
Trying out different data and different network structures is a rather mechanical process. Don’t have too many neurons or you may train too well for the set of documents you have (overfitting), and conversely try to have enough to solve the problem well. Here are the results, varying the number of lines used (1L-3L) and the number of attributes per line (1A-3A):
尝试不同的数据和不同的网络结构是比较机械的过程。不要使用太多的神经元和使用太好的文本集合来训练(过拟合),相反地应当尝试解决足够多的问题。使用不同的行数(1L-3L)和每一行不同的属性(1A-3A)得到的结果如下:
从HTML文件中提取正文的简单方案第4张
The interesting thing to note is that 0.5 is already a pretty good guess at a fixed threshold (see first set of columns). The learning algorithm cannot find much better solution for comparing the density alone (1 Attribute in the second column). With 3 Attributes, the next SLP does better overall, though it gets more false negatives. Using multiple lines also increases the performance of the single layer perceptron (fourth set of columns). And finally, using a more complex neural network structure works best overall — making 80% less errors in filtering the lines.
有趣的是作为一个猜测的固定阈值,0.5的表现非常好(看第一列)。学习算法并不能仅仅通过比较密度来找出更佳的方案(第二列)。使用三个属性,下一个SLP比前两都好,但它引入了更多的假阴性。使用多行文本也增进了性能(第四列),最后使用更复杂的神经网络结构比所有的结果都要更好,在文本行过滤中减少了80%错误。
Note that you can tweak how the error is calculated if you want to punish false positives more than false negatives.
注意:你能够调整误差计算,以给假阳性比假阴性更多的惩罚(宁缺勿滥的策略)。
Conclusion
结论
Extracting text from arbitrary HTML files doesn’t necessarily require scraping the file with custom code. You can use statistics to get pretty amazing results, and machine learning to get even better. By tweaking the threshold, you can avoid the worst false positive that pollute your text output. But it’s not so bad in practice; where the neural network makes mistakes, even humans have trouble classifying those lines as “content” or not.
从任意HTML文件中抽取正文无需编写针对文件编写特定的抽取程序,使用统计学就能获得令人惊讶的效果,而机器学习能让它做得更好。通过调整阈值,你能够避免出现鱼目混珠的情况。它的表现相当好,因为在神经网络判断错误的地方,甚至人类也难以判定它是否为正文。
Now all you have to figure out is what to do with that clean text content!
现在需要思考的问题是用这些“干净”的正文内容做什么应用好呢?

垂直搜索-网页正文提取

原文链接:http://www.beijing-open-party.org/大体上看,目前的文字抓取方式,无外乎以下三种方法:
  • 通过正则表达式抓取:通过诸如BeautifulSoup这样的工具进行。
    • 方法简单,但是性能可能会有问题。与所抓取的目标网页依赖过大,一旦网页格式发生变动,就需要对抓取的方式进行一些更新。出于偷懒的原则,如果程 序能够自动识别变化,那样才比较完美。
  • 标签特征,本话题所述方法即属于此类别。
  • 基于视觉的处理,跨越标签领域,有一些的技术门槛,此话题暂不涉及。
    • (在2009年2月的OpenParty” 有狐”活动中,有位来自雅虎中国的朋友分享了一篇在“服务器端使用Firefox进行网页抓取和内容识别工作”的话题,实际上就是基于视觉的处理 实现)

基于文本密度算法的实现,是上述的标签特征类别的方法。基本公式:纯文本字符数/HTML源码字符数。

原始方法:

  1. 记录HTML标签起始位置
  2. 统计HTML源码首尾包括的字符数和其中的文本字符数

使用Python的matplotlib对统计的结果进行图示查看,从直方图中直观地可以发现,网页中有一部分的文本密度明显高于其它部分。在整个 过程中还可以使用Tidy软件包来清理HTML代码,实例中演示的Sina页面,使用Tidy进行清理后进行识别的效果要好很多。

从实际状况出发,对算法进行小调整:从以前的文本前后判断,变成标签前后判断。

优点:数据的整体性更好。
缺点:数据的分布情况不够直观,有干扰。可以适当地加入一些值的过滤方式来实现

整个实现方法所使用的代码量:加入注释以及模式过滤的原脚本大约有200多行Python代码,如果是根据网上论文的原始实现,大约100多行 Python代码。

所参考、的论文中描述的人工智能文本识别方法:

  • 使用神经网络模型
    • 可使用FANN库,有相应的Python封装
  • 采用原始的一刀切方式,会有丢行的现象产生。
  • 个别行的密度会比较小。

神经网络模型的算法,可以采用机器进行学习的方式进行。不过要注意,学习所采用的原料和实际使用中所针对的目标相似度的关系也很重要。学习的量较 少,可能会达不到完成任务 所需的精度;而学习量过大,出现”过学习”的状况,也可能会出现过度吻合,从而导致对目标数据的变化非常敏感。

其它智能方法,针对HTML标签序列:

  • 统计方法
  • 贝叶斯
  • 马尔可夫
  • CRF

不过为了达成我们的目标,找到最窍门的地方,才是最关键的。比如在很多应用场合下,看似粗旷的’一刀切’方法可能效果也非常不错。

这里介绍的自然语言识别只是一个具体的分支应用,而这个大领域还包括很多其他的内容,如逐渐变热的分词技术,也是值得关注的。

总的来说,自然语言识别技术需要根据应用领域、应用环境来提供相应的解决方案。没有银弹!

我一知半解的记录肯定略有偏差,想要详细了解此内容的朋友(如查阅上文提到的论文等内容),欢迎访问宋博士”提取HTML文档正文“的页面以及他的Blog访问详情。

宋博的原文我也先给贴出来,地址:http://www.elias.cn/MyProject/ExtMainText

ExtMainText —— 提取html文档正文

1.  简介

这是一个使用Python语言实现的函数库,能够帮助从html文档中提取文档正文,换句话说也就是能够过滤页面上的广告、栏目导航等非正文内容。 此函数库可以用在从其他网站抓取文章内容的过程中,以及帮助搜索引擎抓取器忽略无关内容,将页面分析集中到网页更有价值的部分。

函数实现的基本原理是“正文标签密度法”,0.2版本计算网页每个html标签下的“正文长度/标签下所有字符总 长”,取文档中密度高于制定阈值的最长部分作为文档正文输出。原理见:The Easy Way to Extract Useful Text from Arbitrary HTML

对不同网站,因其语言特征及模板外观设计不同,而应当分别指定不同的密度阈值,具体应该根据所有标签的密度分布状况 实验确定。一般英文网站可以取阈值0.5,中文网站使用0.5作为阈值同样能得到不错的输出结果。

  • 当filterMode为 False 时,代码仅返回最长的一段正文,有可能会将博客的评论信息等过滤掉(当评论文字都比较短的时候);
  • 当filterMode为 True 时,代码会过滤掉密度低于阈值的html片段,也即能够保留多段正文文字,从而通常可以保留博客的评论信息。

函数最终输出的是包含文档正文的html片段,如果需要将提取的正文内容进一步转换为text 纯文本内容,则可以调用html2text

English Doc, See:En.ExtMainText

2.  脚本下载

2.1  更新记录

  • 2010-01-26:解决有时html文本中的特殊字符造成编码错误的问题。
  • 2009-12-05:改为使用lxml api实现,使用新的密度计算公式,并增加“使用过滤模式”的选项。
  • 2008-10-21:在__main__部分添加html向text转换的代码,直接执行ExtMainText将给出更直观的输出;作为0.1a版本发布。
  • 2008-10-19:完成基本功能,作为0.1版本发布。

3.  使用说明

作为库函数使用时可参照源代码的DocString以及“ if __name__ == ‘__main__’ ”部分。也可以直接运行此脚本文件:

python ExtMainText.py 输入的html文件名

这样脚本将以默认参数(0.5)提取该html文件的正文内容,并转换为纯文本输出。另外请注意输入的html文本的编码,在0.2a之后的版本只接受unicode文本作为输入,因此需要提前完成对 输入文档的解码。

4.  后续改进方向

相对于固定阈值,使用神经网络等智能方法能够获得更为准确的输出,建议参考也谈网页正文提取[下]以及赖勇浩先生翻译的从HTML文件中抽取正文的简单方案

5.  与其他实现的比较

也谈网页正文提取[下]The Easy Way to Extract Useful Text from Arbitrary HTML两 篇文章的非人工智能算法的部分(也就是使用静态阈值方法来提取文章正文)在算法和代码实现上都是完全一样的。虽然都是使用文本密度来识别文章正文部分,但 他们对文本密度的计算方法和我的还是存在一定区别,这里以我个人的理解进行简单的比较分析。

他们在计算文本密度时,从头至尾逐步解析html,当遇到一行纯文本内容时,以这一行纯文本的长度作为“文本长 度”,以这一行纯文本结束位置到上一行纯文本结束位置在原始html中所跨越的字符总数作为“字符长度”,并用两者的比值作为文本密度的值。这种计算方法 存在一定的不合理性。从物理意义上来讲,“字符长度”应该是与修饰一段纯文本相关的html代码 总长。但他们的计算方法是将纯文本之前的html标签作为其修饰成分,对于前后匹配的html标签来说,特别是纯文本被括在多层表格 及<div>标签之内的情况,不能保证将各层标签的结束标签算作此段纯文本的修饰内容,相反却很可能将之计算为下一行纯文本所对应的字节长度 组成部分。在极端条件下,也即分析第一行纯文本时,算法会将之前的所有html标签算作字节组成部分,也即包含了<head>部分,这不合理 地极大地降低了密度的取值。虽然扫描一般html页面遇到的第一行纯文本通常是菜单或者导航部分,需要作为正文提取的可能性不大,但这种算法实现方法与其 预期体现的物理意义不能很好地吻合。

我的实现则将每个html标签下涵盖的所有内容作为整体来分析,比如对一个<div>标签,算法将此起 始标签与其对应结束标签之间包括的所有纯文本内容作为“文本长度”,包括的所有字节内容作为“字节长度”,如此计算文本密度,可以保证所涉及的字节一定是 与对应的纯文本密切相关的。因此对于静态阈值方法来说,估计能够获得稍好的正文提取准确度。

当然,那两篇文章的方法也有一定好处,就是对纯文本内容按照行来区分,对后续人工智能的训练和处理过程来说更便于人 的操作和理解。但文中提及的神经网络方法并不是唯一的选择,或许可以不考虑文本行,而是从 html 标签的出现顺序上寻找规律。

免责声明:文章转载自《从HTML文件中提取正文的简单方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Overleaf 平台的使用访问 IIS 元数据库失败 的解决方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

字符串匹配算法

一、简介 文本信息可以说是迄今为止最主要的一种信息交换手段,而作为文本处理中的一个重要领域——字符串匹配,就是我们今天要说的话题。(原文还特意提及文本数据数量每18个月翻一番,以此论证算法必须要是高效的。不过我注意到摩尔定律也是18个月翻番,这正说明数据的增长是紧紧跟随处理速度的,因此越是使用高效的算法,将来待处理的数据就会越多。这也提示屏幕前的各位,代码...

第二章 JSP页面制作基础

第二章  JSP页面制作基础 [本章导读] JSP页面将Java代码嵌入到HTML脚本中,掌握HTML语言是学习JSP的基础。HTML是网页制作的一种规范,一种标准,它通过标记符来标记网页的各个部分。本章首先介绍用HTML制作网页的各种标记符的设置方法,接着介绍了CSS的基本概念和使用方法。此外,为了增强读者对网页制作的了解,介绍了Dreamweaver的...

使用kaptcha生成验证码

kaptcha是一个简单好用的验证码生成工具,通过配置,可以自己定义验证码大小、颜色、显示的字符等等。   1、下载kaptcha。     http://code.google.com/p/kaptcha/downloads/list   2、新建一个Web项目,并将下载压缩包中的kaptcha-2.3.2.jar放在项目的WEB-INF/lib目录下。...

解析HTML文件

运用.NET Framework类来解析HTML文件、读取数据并不是最容易的。虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的API并不是“取出即可用(out of the box)”的,因为HTML的格式不规范。你可以用正则表达式(regular expression),但如果你对...

GoEasy接口测试Websocket

GoEasy接口测试Websocket1.  登陆GoEasy官网:https://hangzhou.goeasy.io/cn/home 2.  注册账号  登陆GoEasy官网   4.进入我的应用,查看goeasy接口信息           ru 附源代码: <!DOCTYPE html> <html lang="en">...

带你由浅入深探索webpack4(一)

 相信你或多或少也听说过webpack、gulp等这些前端构建工具。近年来webpack越来越火,可以说成为了前端开发者必备的工具。如果你有接触过vue或者react项目,我想你应该对它有所了解。 这几天我重新整理了一下webpack中知识点,把一些常用到的总结出来,希望能帮助到大家以及加深自己对webpack的理解。 (由于我在写这篇文章的时候webpa...