这里所说的正文提取主要是针对新闻页面等网页的主体是文字的HTML页面。在做一些与文本处理相关的实验时往往需要大量的文本,虽然网络上已经存在了一些开放数据集如搜狗语料库,但是有的时候也需要根据具体的需求来爬取特定的网站。在我们通过算法获得了需要的HTML页面以后,如何获取页面的正文是一个需要考虑的问题。如果是针对某一个网站的爬取工作,同一网站编码风格往往是一致的,这时只需要简单的浏览一下包含正文的标签,就能发现规律(一个网站的网页正文一般都包含在具有指定id或class的标签下,或者可以根据多个属性的组合来定位正文,因为所有的包含正文的标签结构是一致的)。但是如果在像百度新闻这样的搜索平台中爬新闻,不同的网页来自于不同的网站,没有固定的结构,就需要一种通用的方法。这里我介绍一种自己想到的方法,针对绝大多数的新闻网站都可以有效的提取正文。

这个方法其实思路很简单,分为以下三个步骤:

1. 提取所有的div标签。

2. 提取每一个div标签里包含的p标签内容并保存在变量content中,对于div标签中嵌套的div标签直接过滤掉。

3. 保存具有最长size的content作为该网页的正文。

在研究了很多HTML页面之后,我发现所有的正文都包含在div标签中,而且他们之间的层次关系很近,所以以div标签为出发点可以最大程度减小搜索范围。由于正文多被一个或多个p标签包含,所以单纯的搜索p标签是不切实际的,但是p标签可以作为一种最细化的条件来进行div标签内正文的提取,因为有的时候div标签里还会有其他的标签包括文本内容,比如a标签等,这些是不算正文内容的。当然如果一个div中嵌套了包含正文的div,假如这个div中又恰好包含了含p标签的无用文本,那么这个算法会把正文以及无用文本都提取出来,为了避免这种情况的发生,我们在遍历div标签时如果遇到嵌套的div会直接跳过(反正之后这个嵌套div还是会被我们搜索的)。最后,由于该页面是以文字内容为主体的,所以包含最多字符的div标签,也就是最长size的content为该网页的正文。

下面贴一下demo代码:

package getContent;import java.io.IOException;
import java.util.Stack;import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;public class getContent {static int index;/*** @param args* @throws IOException */public static void main(String[] args){String url = "http://www.taiwan.cn/taiwan/tw_Story/201301/t20130125_3590110.htm";Document doc = null;try {doc = Jsoup.connect(url).get();} catch (IOException e) {e.printStackTrace();} String content = GetDocContent(doc);System.out.println("网页正文如下:\n"+content);}private static String GetDocContent(Document doc) {Elements divs =  doc.body().getElementsByTag("div");int max = -1;String content = null;for (int i=0; i<divs.size(); i++) {Element div = (Element)divs.get(i);String divContent = GetDivContent(div);if (divContent.length() > max) {max = divContent.length();content = divContent;}}return content;}private static String GetDivContent(Element div) {StringBuilder sb = new StringBuilder();//考虑div里标签内容的顺序,对div子树进行深度优先搜索Stack<Element> sk = new Stack<Element>();sk.push(div);while (!sk.empty()) {//Element e = sk.pop();//对于div中的div过滤掉if (e != div && e.tagName().equals("div")) continue;//考虑正文被包含在p标签中的情况,并且p标签里不能含有a标签if (e.tagName().equals("p") && e.getElementsByTag("a").size() == 0) {String className = e.className();if (className.length() != 0 && className.equals("pictext")) continue;sb.append(e.text());sb.append("\n");continue;} else if (e.tagName().equals("td")) {//考虑正文被包含在td标签中的情况if (e.getElementsByTag("div").size() != 0) continue;sb.append(e.text());sb.append("\n");continue;}//将孩子节点加入栈中Elements children = e.children();for (int i=children.size()-1; i>=0; i--) {sk.push((Element)children.get(i));}}return sb.toString();}}

上面的代码使用了JSoup这个包,这是一个用来解析HTML的第三方开源包,网上有很多介绍JSoup的资料。另外对于div标签的遍历我采用的是深度优先搜索,这里主要是考虑到多个p标签情况时,保证这些p标签的相对位置不变,从而能保证正文被正常提取处理,这里记得每个p标签内容提取之后加一个回车。代码里还考虑了正文被包含在td标签的情况,这是我遇到的一些特殊网页出现的情况,一般并不常见。

一种提取HTML网页正文的方法相关推荐

  1. php网页正文提取,通用网页正文抓取工具_任意网页正文提取API

    ArticleExtractor 智能提取任意网页正文内容 无需任何规则,输入目标内容面url地址(网站首页.列表页面除外),可轻松实现对任意新闻网页正文智能提取,并去除广告等与正文无关的内容. 提取 ...

  2. 能提取HTML网页正文的网站,智能提取网页正文新方法

    一.基于中文标点符号和HTML 树 结构的网页正文信息抽取方法H TML ( hyper text markup language) 是超文本标记语言, 是基于标准通用标记语言(SGML) 的一个庞大 ...

  3. 两种简单的网页图片替换方法

    网站具体是由图片.文字.视频组成的,现在搭建网站,一般都是利用模板建站的方式去做,那么我们拿到模板以后,想要去对这个模板一些图片位置进行修改,应该怎么去做呢?那么基于wordpress的模板建站方式, ...

  4. 提取html网页正文信息

    最近陆陆续续尝试了一些解析html的方法,场景不同,说不好孰优孰劣,请自行选择 版本一(goose): py2版本: https://github.com/grangier/python-goose ...

  5. 浏览器怎么录制网页视频?3种网页视频录制方法

    我们每天都会在浏览器上观看大量的视频,尤其是在爱奇艺.腾讯.哔哩哔哩等网页上.有时候就会观看到一些精彩的视频画面,就想要将这些画面给下载. 那怎么把网页视频录制下来?今天本文就给大家分享3种有效的网页 ...

  6. php 正文提取算法,基于机器学习的网页正文提取方法

    摘  要: 先将网页转换为规范的DOM树,然后计算每行文本的文本密度.与标题相关度等值,并将其作为输入参数利用BP神经网络进行训练,进而形成抽取规则,最后通过实验验证该方法的可行性. 关键词: 信息提 ...

  7. golang:正则表达式匹配网页url_网络爬虫:3种网页抓取方法

    3种抓取其中数据的方法.首先是正则表达式,然后是流行的BeautifulSoup模块,最后是强大的lxml模块. 1 正则表达式 如果你对正则表达式还不熟悉,或是需要一些提示,那么你可以查阅https ...

  8. 选定区域着色html,一种提取html页面选定区域内容的方法

    一种提取html页面选定区域内容的方法 [专利摘要]一种提取html页面中选定区域内容的方法.该方法的特征在于,在步骤1中,将html源码转换为元素列表:在步骤2中,针对html源码制定一个分析模板, ...

  9. apk 路由器劫持_一种在路由器上防止网页劫持的方法与流程

    本发明属于网络技术领域,尤其涉及一种在路由器上防止网页劫持的方法. 背景技术: HTTP请求在网络中进行明文传输,传输过程中常常会被网络节点中的路由设备进行连接并修改,以实现广告插入和将请求导流到钓鱼 ...

最新文章

  1. Captaris Workflow 6.0 EventService 执行效率低下的排除。
  2. linux挂载home分区,Linux(CentOS6) 调整 /home 挂载 分区大小
  3. 6 个理由,让我不顾一切撑腰 Python!
  4. 1088 最长回文子串
  5. t30智能插座怎么设置_如何设置ConnectSense智能插座
  6. php16进制密钥签名对接支付,简单理解rsa的加密和签名-PHP实现
  7. 2020-12-15 CPU设计复盘
  8. 固态硬盘 linux 文件系统,SSD是否需要使用特别的文件系统?
  9. asp.net运行时动态修改主题
  10. 对比A,B两张表,将相同的记录写到M表,不同的记录全部写到N表中
  11. 一些JavaScript题目
  12. 【Python-3.3】使用while循环实现列表间数据移动
  13. 红帽linux安装vnc,redhat企业7.0安装VNC
  14. java求sobel算子代码_sobel算子原理与实现
  15. 抖音直播带货攻略;直播前需要准备哪些设备丨国仁网络资讯
  16. 寻找春天nbsp;九宫格日记-2014.04.26
  17. vkt中使用OBJImporter导入模型并进行贴图
  18. 斐波那契(黄金分割法)查找算法(FibonacciSearch)
  19. Vue CLI脚手架详细教程
  20. 微博第三方+海外国际版+V2EX第三方

热门文章

  1. Windows下的免安装版MySQL配置
  2. 想要定制个性化语音?来试试这几个配音软件
  3. 华为KubeEdge在边缘计算的实践
  4. 匹配输入华为:编程实现联想输入法 输入联想功能是非常实用的一个功能,请编程实现类似功能...
  5. 混乱与整齐-布局-PCB系列教程1-12
  6. 【洛谷】P5149 会议座位
  7. 常用的手机宽度 前端切图用 常用的手机尺寸
  8. scratch和平使者 电子学会图形化编程scratch等级考试一级真题和答案解析2022年12月
  9. Java实习(一维)线性回归方程
  10. 为什么计算机起始时间、为什么Java时间戳、是1970年1月1日?