网页电话/手机号码识别

本文介绍了一种无需精确正则表达式的网页电话号码识别方法。通过分析数字序列特征,结合Lucene分词,构建领域模型并计算相关度,对数字序列进行排序推荐,从而找出可能的电话号码。
摘要由CSDN通过智能技术生成

识别网页上的电话号码,一个比较容易想到的方法就是,通过预先设计电话号码的正则表达式,对网页文本内容中电话号码进行匹配,抽取出对应的联系方式。然而,这种方法是假定电话号码都是按照比较理想的格式在网页上展示的,自然对于这样的识别精度会很高,但是同时也漏掉了很多电话号码。如果你没有深入分析处理过Web网页数据,你是想象不到互联网上网页的格式到底有多不规范。

这里,我们实现一种识别网页上电话号码的方法,不需要设计精确的正则表达式来匹配电话号码,而是通过电话号码最抽象的特征来考虑和设计。

电话号码一定是一个含有数字的序列,而且可能数字之间通过一些特殊或常见的字符来进行分隔,比如“逗号”、“短线”、“空格”、“字母”等等。我们通过对一个页面的文本内容进行分析,将放宽数字字符串的定义:

如果两个数字字符之间连续,则认为两个数字字符属于同一个序列;如果两个数字字符之间存在小于给定阈值限制个数的非数字字符,则认为这两个数字字符也属于同一个序列。这种观点的实质是,将距离比较近的数字字符串合并为一个独立的序列,这样,通过分析一个页面的文本内容就可以得到一个数字字符序列的集合。

然而,这样会把比较短的数字,如日期、年龄、序号等都分析出来。自然而然想到,通过过滤算法将其过滤掉。我们这里通过一种推荐模型,计算每个数字字符序列的相似度,然后根据相似度进行排序,再从排序靠前的数字字符串序列中筛选出电话号码。

下面,看看我们用Java实现这个思路,并观察一下结果。

定义一个序列推荐接口SequenceRecommendation,recommend方法是具体的实现逻辑,可以根据自己的需要去设计。

package org.shirdrn.webmining.recommend;

public interface SequenceRecommendation {
	public void recommend() throws Exception;
}

下面,我们实现一个用来抽取数字字符串序列的算法,并计算相关度,从而进行排序推荐。基本思路如下:

1、清洗原生的网页:将HTML标签等等都去掉,得到最终的文本内容。

2、对文本内容进行分词:使用Lucene自带的SimpleAnalyzer分析器(未使用停用词过滤),之所以选择这个是因为,在数字字符序列附近(前面和后面)存在某些具有领域特定含义的词(如电话号码数字前面和后面可能存在一些词:phone、telephone等;Email地址附近可能存在一些词:email、email us等;等等),可能它是一个停用词(对StandardAnalyzer等来说),我们不希望过滤掉这些词。另外,我们记录了每个词的位置信息。

3、聚集数字字符序列,同时记录前向和后向指定数量的词(核心):这个应该是最核心的,需要精细地处理文本内容,和设计数据结构,得到一个我们能够方便地进行相关度计算的结果集。

4、根据一个样本集的计算结果,来建立领域模型(特征词向量),用于计算数字字符序列的相关度:我这里收集了一部分英文网页,通过英文网页的分析处理,提炼出一批特征词,为简单起见直接使用词频作为权重(注意:这样使用词频简单而且合理,也可以采用其他的方法进行权重的计算,或者补充其它属性权重的贡献)。我们这里使用了两个特征词向量,分别如下所示:

前向特征词向量(文件forwards_feature_vector):

email                                     9124
e                                         3368
mail                                      4767
e-mail                                    2183
email us at                               178
fax                                       147
email address                             146
email us                                  121
fx                                        115
or                                        113
email us                                  102
email or                                  95
email us at                               76
or e-mail                                 67

后向特征词向量(文件backwards_feature_vector):

phone                          27407
call						   13697
free						   13092
toll						   10092
toll free                      9012
tel                            8710
call                           5247
telephone                      4052
call us                        3108
ph                             3067
t                              2838
p                              2830
contact us                     2150
or call                        1889
local                          1477
f                              1437
or                             1362
abn                            1257
call us at                     1194
office                         1183
call us today                  1152
customer service               1101
call toll free                 1080

我们的特征词向量是通过文件形式导入,在后面的测试用例中使用。

5、相关度排序,并进行推荐:这里排序后就可一目了然,排在前面的是电话号码的可能性最大。

下面是整个思想的设计及其实现,NumberSequenceRecommendation类的代码,如下所示:

package org.shirdrn.webmining.recommend;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.en.EnglishAnalyzer;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.apache.lucene.util.Version;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.parser.Parser;

public class NumberSequenceRecommendation implements SequenceRecommendation {

	private byte[] content;
	private Charset charset;
	private String baseUri;
	
	/** Max count of non-number number sequence in a continual number sequence, 
	 * on conditions of which we think the number sequence is continual.*/
	private int maxGap = 5;
	/** Max word count after or before a number sequence */
	private int maxWordCount = 5;
	private Pattern numberPattern = Pattern.compile("^\\d+$");
	private String cleanedContent;
	
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值