网页正文抽取(包含提取图片)
2014-09-05 13:37
246 查看
转自:http://bbs.it-home.org/thread-12676-1-1.html
PS:
Q:经常看见的正则前面的 (?i) (?s) (?m) (?is) (?im) 是什么意思?
A: 称为内联匹配模式,通常用内联匹配模式代替使用枚举值RegexOptions指定的全局匹配模式,写起来更简洁。
(?i) 表示所在位置右侧的表达式开启忽略大小写模式
(?s) 表示所在位置右侧的表达式开启单行模式。
更改句点字符 (.) 的含义,以使它与每个字符(而不是除 \n 之外的所有字符)匹配。
注意:(?s)通常在匹配有换行的文本时使用
(?m) 表示所在位置右侧的表示式开启指定多行模式。
更改 ^ 和 $ 的含义,以使它们分别与任何行的开头和结尾匹配,
而不只是与整个字符串的开头和结尾匹配。
注意:(?m)只有在正则表达式中涉及到多行的“^”和“$”的匹配时,才使用Multiline模式。
上面的匹配模式可以组合使用,比如(?is),(?im)。
另外,还可以用(?i:exp)或者(?i)exp(?-i)来指定匹配的有效范围。
/** *@author Xin Chen *Created on 2009-11-11 *Updated on 2010-08-09 *Email: xchen@ir.hit.edu.cn *Blog: http://hi.baidu.com/爱心同盟_陈鑫 *Modified By : Yang @ http://www.chainlt.com */ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import dbhelper.TextTool; /** * <p> * 在线性时间内抽取主题类(新闻、博客等)网页的正文。 采用了<b>基于行块分布函数</b>的方法,为保持通用性没有针对特定网站编写规则。 * </p> * * @author Chen Xin * @version 1.0, 2009-11-11 */ public class TextExtract { private static List<String> lines; private final static int blocksWidth; private static int threshold; private static String html; private static boolean flag; private static int start; private static int end; private static StringBuilder text; private static ArrayList<Integer> indexDistribution; private static List<String> old_lines; private static String oldhtml; static { lines = new ArrayList<String>(); indexDistribution = new ArrayList<Integer>(); text = new StringBuilder(); blocksWidth = 3; flag = false; /* 当待抽取的网页正文中遇到成块的新闻标题未剔除时,只要增大此阈值即可。 */ /* 阈值增大,准确率提升,召回率下降;值变小,噪声会大,但可以保证抽到只有一句话的正文 */ threshold = 86; } public static void setthreshold(int value) { threshold = value; } /** * 抽取网页正文,不判断该网页是否是目录型。即已知传入的肯定是可以抽取正文的主题类网页。 * * @param _html * 网页HTML字符串 * * @return 网页正文string */ public static String parse(String _html) { return parse(_html, false); } /** * 判断传入HTML,若是主题类网页,则抽取正文;否则输出<b>"unkown"</b>。 * * @param _html * 网页HTML字符串 * @param _flag * true进行主题类判断, 省略此参数则默认为false * @return 网页正文string */ public static String parse(String _html, boolean _flag) { flag = _flag; html = _html; preProcess(); // System.out.println(html); return getText(); } private static void preProcess() { html = html.replaceAll("(?is)<!DOCTYPE.*?>", ""); html = html.replaceAll("(?is)<!--.*?-->", "");// remove html comment html = html.replaceAll("(?is)<script.*?>.*?</script>", "");// remove // javascript html = html.replaceAll("(?is)<style.*?>.*?</style>", "");// remove css html = html.replaceAll("(?is)style=\".*?\"", "");// remove css html = html.replaceAll("&.{2,5};|.{2,5};", " ");// remove special char oldhtml = html; html = html.replaceAll("(?is)<.*?>", ""); // <!--[if !IE]>|xGv00|9900d21eb16fa4350a3001b3974a9415<![endif]--> } private static String getText() { lines = Arrays.asList(html.split("\n")); old_lines = Arrays.asList(oldhtml.split("\n")); indexDistribution.clear(); boolean haveimg_arr[] = new boolean[old_lines.size()]; for (int i = 0; i < lines.size() - blocksWidth; i++) { int wordsNum = 0; for (int j = i; j < i + blocksWidth; j++) { lines.set(j, lines.get(j).replaceAll("\\s+", "")); wordsNum += lines.get(j).length(); } indexDistribution.add(wordsNum); // System.out.println(wordsNum); if (old_lines.get(i).toLowerCase().contains("<img")) { haveimg_arr[i] = true; } } start = -1; end = -1; boolean boolstart = false, boolend = false; text.setLength(0); for (int i = 0; i < indexDistribution.size() - 1; i++) { if (indexDistribution.get(i) > threshold && !boolstart) { if (indexDistribution.get(i + 1).intValue() != 0 || indexDistribution.get(i + 2).intValue() != 0 || indexDistribution.get(i + 3).intValue() != 0) { boolstart = true; start = i; continue; } } if (boolstart) { if (haveimg_arr[i]) { continue; } if (indexDistribution.get(i).intValue() == 0 || indexDistribution.get(i + 1).intValue() == 0) { end = i; boolend = true; } } if (boolend) { StringBuilder tmp = new StringBuilder(); // System.out.println(start+1 + "\t\t" + end+1); for (int ii = start; ii <= end; ii++) { if (haveimg_arr[ii]) { String img = getImg(old_lines.get(ii)); if (img == null) continue; tmp.append(img + "\n"); continue; } if (lines.get(ii).length() < 5) continue; tmp.append("<p>" + lines.get(ii) + "</p>\n"); } String str = tmp.toString(); // System.out.println(str); if (str.contains("Copyright") || str.contains("版权所有")) continue; text.append(str); boolstart = boolend = false; } } return text.toString(); } public static String getImg(String s) { String img = TextTool.getBetweenOne(s, "<img", "</img>"); if (img == null) { img = TextTool.getBetweenOne(s, "<img", "/>"); } else { img = "<img" + img + "</img>"; } if (img != null) { img = "<img" + img + "/>"; } return img; } }
PS:
Q:经常看见的正则前面的 (?i) (?s) (?m) (?is) (?im) 是什么意思?
A: 称为内联匹配模式,通常用内联匹配模式代替使用枚举值RegexOptions指定的全局匹配模式,写起来更简洁。
(?i) 表示所在位置右侧的表达式开启忽略大小写模式
(?s) 表示所在位置右侧的表达式开启单行模式。
更改句点字符 (.) 的含义,以使它与每个字符(而不是除 \n 之外的所有字符)匹配。
注意:(?s)通常在匹配有换行的文本时使用
(?m) 表示所在位置右侧的表示式开启指定多行模式。
更改 ^ 和 $ 的含义,以使它们分别与任何行的开头和结尾匹配,
而不只是与整个字符串的开头和结尾匹配。
注意:(?m)只有在正则表达式中涉及到多行的“^”和“$”的匹配时,才使用Multiline模式。
上面的匹配模式可以组合使用,比如(?is),(?im)。
另外,还可以用(?i:exp)或者(?i)exp(?-i)来指定匹配的有效范围。
相关文章推荐
- 网页正文抽取演示(包含组件下载地址、原理说明文章地址)
- 表达式从网页html代码中提取图片的scr地址!
- 蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题
- C#发送邮件时在正文中插入图片(邮件中直接包含图片)
- cx-extractor:基于行块分布函数的通用网页正文抽取:线性时间、不建DOM树、与HTML标签无关
- 有《基于行块分布函数的通用网页正文抽取》想到的
- 根据网页源代码提取图片地址的asp代码
- 网页提取正文
- 使用php代码从网页中提取有效图片地址
- 新闻类网页正文提取系列
- asp.net正则表达式提取网页网址、标题、图片,滤所有HTML标签
- [导入]蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题
- 将所有图片包含在一张图片中,以提高网页访问速度
- 将所有图片包含在一张图片中,以提高网页访问速度
- 目前互联网上公布出来的正文提取算法,大家可以综合比较下,一起来测试下哪个更好用。 词网--北京词网科技有限公司 http://demo.cikuu.com/cgi-bin/cgi-contex 猎兔网页正文提取 http://www.lie
- 提取网页的图片链接的Java程序
- [原]基于统计的中文网页正文抽取的研究
- 网页正文内容的提取
- 动态提取网页中的图片地址
- asp.net正则表达式提取网页网址、标题、图片实例以及过滤所有HTML标签实例