利用Tesseract识别58同城图片式手机号码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用Tesseract识别58同城图片式手机号码相关的知识,希望对你有一定的参考价值。

58同城上的手机号码大多数是图片格式,目的也是防止爬虫软件抓取,但作为一个专门开发爬虫的程序猿,必须拿下它才能安心,否则睡觉做梦也会想着该怎么破这该死的图片号码的!

这里我们利用Google的开源项目:Tesseract-ocr(项目地址:https://github.com/tesseract-ocr)

其实,Tesseract的网上的教程其实有很多,关于它的介绍,我在这里就不说了,直接讲重点!

先是要初始化Tesseract,这里我们用默认的识别库,根据58同城号码图片的特点,我们这样初始化下:

//程序里需要引用:Tesseract.dll以及程序根目录下要有tessdata\\eng.traineddata的识别库文件

Tesseract.TesseractEngine te = new TesseractEngine(Application.StartupPath + "\\tessdata", "eng", EngineMode.Default);//初始化,这里利用默认的识别库

te.SetVariable("tessedit_char_whitelist", "0123456789");//设置识别的字符白名单

te.DefaultPageSegMode = PageSegMode.SingleLine;//设置识别模式为单行模式

注意的是.NET版本貌似必须3.5及以上,否则Tesseract初始化总是不通过。此问题之前困扰了我好久。

首先我们拿到58同城上的图片号码地址如下:

http://image.58.com/showphone.aspx?t=v55&v=6E0C227B5A963FC4VD7B70A4FC12D1D01

下载获取得到下面的图片:

技术分享

先对图片进行二值化算法(就是变成只有黑白的算法,搜索引擎一搜一堆)得到下面的图片:

技术分享

这种单色的图片对于OCR引擎来说就友好多了,识别算法:

我们设定一个Bitmap类型变量bTelImg存储这个二值化后的号码图片,String类型sTelNumber用来存数识别结果,利用下面的算法得到识别结果:

Page PG = te.Process(PixConverter.ToPix(bTelImg), PageSegMode.SingleLine);

sTelNumber= KeyReplace(PG.GetText());

识别下:

技术分享

额... 一万只草泥马奔腾而过,错这么多咋办?难道要用Tesseract的高级训练算法训练个自己的库出来?都说简单识别了,别搞那么复杂好不好,我好懒的!

其实58上这个图片是动态生成的,所以每次访问得到的图片都不一样,包括号码间隔等。第一次下载的图片因为字符图片粘连的问题,导致识别结果不正确,我们对同样的地址再下载一次图片:

技术分享

二值化:

技术分享

识别:

技术分享

哈哈,终于对了!
证明这个免费的OCR引擎直接下载下来不用复杂的训练还是有效的,下面我们在不改变识别算法的前提下,提高识别率(毕竟对于这种纯数字的图片,想OCR的识别率高,只能训练或者写专门的OCR引擎了)

因为第一次识别结果错了,第二次再下载图片,结果却对了。所以我们可以从识别结果下手,不对我们就重新下载图片,再次识别,直到正确或者设定个阀值,达到阀值,不正确我也没办法了!免费的只能这样了!

因为这里我们识别的是手机号码,所以知道手机号码的规律,我们再对结果进行判断,就可以初步判定结果的争取性了!

  1. 手机号码必须为11位纯数字(因为我们设置的白名单是纯数字,所以保证结果是11位就可以了)

  2. 手机号码必须为13,15,18开头的(这个能排除一大部分错误了)

嗯,差不多这两条结果规则可以有效提高识别率了。算法我这里就不写了,是个程序猿都会吧?

至此,一个简单的58 的手机号码图片就完成了。其他诸如电话号码,简单字符验证码,原理也差不多。希望能给初学者一点帮助,后面有机会再和大家讲讲更高级的OCR识别方法。


以上是关于利用Tesseract识别58同城图片式手机号码的主要内容,如果未能解决你的问题,请参考以下文章

58同城首页UI渲染优化

爬虫-Tesseract

Android tesseract-orc之扫描身份证号码

利用AForge+Tesseract制作视频OCR程序

利用python爬取58同城简历数据

利用卷积神经网络实现手写字识别