【VSRC唯科普】简易图像识别与文字处理(第11/14篇)

百家 作者:唯品会安全 2020-03-24 20:12:54

鸣 谢

VSRC感谢业界小伙伴——Mils 投稿精品科普类文章。VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将有好礼相送,我们已为您准备好了丰富的奖品!

(活动最终解释权归VSRC所有)


在本次的唯科普里,我们将重点介绍机器视觉的一个分支:文字识别。介绍如何使用一些Python库来识别和使用在线图片中的文字。当你不想让自己的文字被网络机器人采集时,把文字做成图片放在网页里,会是最常用的办法之一,例如我们经常会看到一些邮箱地址中的部分内容或全部内容,被转换成了图片,当机器人阅读此类图片时,便会非常困难,这种方法可以防止多数垃圾邮件发送器,轻易的获取真实的邮箱地址。利用这种人类可以正常读取,大多数机器人无法读取的图片,验证码(CAPTCHA)就出现了。但是,验证码并不是网络爬虫数据采集时,需要将图像转换为文字的唯一对象。将图像翻译成文字,一般称为光学文字识别(OCR,Optical Character Recognition)。







1、Tesseract库概述




在读取和处理图像、图像相关的机器学习以及创建图像等任务中,Python有很多库可以进行图像处理,例如Tesseract库。Tesseract库目前由Google赞助,Tesseract库也是目前公认最优秀、最精准的开源OCR系统。除了极高的精准度,也具有很高的灵活性。通过有效的训练,可以识别出任何字体及Unicode字符。







2、处理格式规范的文字




通常,格式规范的文字具有以下特点:

  • 使用一个标准字体,虽然被复制或被拍照,但是字体还是清晰的,并且没有多余的痕迹;

  • 排列整齐且没有歪歪斜斜的字;

  • 没有超出图片范围的内容;

  • 也没有残缺不全或紧贴在图片的边缘;

例如以下这段规范文字示例:

我们使用 tesseract  text1.tif textoutput | dir textoutput.txt 命令将其内容进行读取并将结果写到一个文本文件中:

D:\Program Files\Tesseract-OCR>tesseract  text1.tif textoutput | dir textoutput.txt
Volume in drive D has no label.
Volume Serial Number is 2695-512E
Directory of D:\Program Files\Tesseract-OCR
Tesseract Open Source OCR Engine v5.0.0-alpha.20200223 with Leptonica

运行这段命令后,会输出Tesseract版本信息:Tesseract Open Source OCR Engine v5.0.0-alpha.20200223 with Leptonica ,表明程序正在运行,后面是图片识别结果textoutput.txt文件里的内容,并且我们可以看到,识别的结果还是非常准确的。

This is some text,written in Arial,that will be read by
Tesseract. Here are some symbols: !@##$%%()







3、从网站图片中抓取文字



网站上的图片有些看起来丰富多彩,但其文字内容对爬虫来说却并不太直观,并且图书的预览页面通常不会允许爬虫采集,例如Amazon图书的预览页面,会通过Ajax脚本进行加载,预览图片也会隐藏在div节点内,这对于普通的访问者而言,他们看起来更像是一个Flash动画,而不是一个图片文件。

采集此类文字,我们可以使用Selenium+WebDriver+Tesseract相结合的方式来实现,以托尔斯泰的《War and Peace》为例,采集的整体思路为:先导航到托尔斯泰的《War and Peace》页面,然后打开阅读器,收集图片的URL链接,最后下载图片,识别图片,打印图片内的文字。以下为对应实现的代码,其中除了在《Web Scraping with Python》中提及到的内容,VSRC唯科普还会将具体元素的定位方式进行讲解,以帮助读者更直观的理解这段代码背后具体所执行的操作。


(1)首先让我们导入一些运行程序所必须依赖的Python库:


# encoding=utf8
import time
from urllib.request import urlretrieve
import subprocess
from selenium import webdriver


(2)接着启动Chrome浏览器:


driver = webdriver.Chrome(executable_path='C:\chromedriver.exe')
driver.get(
    "https://www.amazon.com/War-Peace-Leo-Nikolayevich-Tolstoy/dp/1427030200"
)
time.sleep(2)


(3)使用WebDriver定位sitbLogoImg元素:


并调用JavaScript执行点击操作:

ele = driver.find_element_by_id('sitbLogoImg')
driver.execute_script("arguments[0].click();", ele)
time.sleep(5)


(4)使用WebDriver定位sitbReaderRightPageTurner元素:


读取预览页内容,并选取所有class元素,且这些元素拥有值为pageImage的class属性。

imageList = set()
while "pointer" in driver.find_element_by_id('sitbReaderRightPageTurner').get_attribute("style"):
    driver.find_element_by_id("sitbReaderRightPageTurner").click()
    time.sleep(2)
    pages = driver.find_elements_by_xpath("//div[@class='pageImage']/div/img")
    for page in pages:
        image = page.get_attribute("src")
        imageList.add(image)
        if len(imageList) > 3:  
            break
driver.quit()

使用tesseract对页面内容进行分析,收集图片的URL链接:

for image in sorted(imageList):
    urlretrieve(image,"page.jpg")
    p = subprocess.Popen(["D:\\Program Files\\Tesseract-OCR\\tesseract.exe","page.jpg","page"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    p.wait()
    f = open("page.txt","r")
    print (f.read())

最终输出如下:

我们将其中部分内容,与原文内容比对后,很明显的能发现,通过程序读取的内容还原度整体较高。







4、读取验证码与训练Tesseract




虽然大部分对单词CAPTCHA都很熟悉,但是很少人知道它的具体含义:Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称。训练Tesseract识别一种文字,无论是晦涩难懂的字体还是验证码,我们都需要向Tesseract提供每个字符不同形式的字体。第一步是把大量的验证码样本下载到一个文件夹里,第二步是准确的告诉Tesseract一张图片中每个字符是什么,以及每个字符的具体位置。手工创建定位文件通常会耗费大量时间。详情可参考:https://github.com/tesseract-ocr/tesseract/wiki 







5、获取验证码提交答案




大多数网站生成的验证码图片都具有以下属性:

  • 他们设计服务器端的程序动态生成的图片,验证码图片的src属性,可能会和普通图片不太一样,比如<img src="WebForm.aspx?id=8ASDSADA">,但是可以和其他 图片一样进行下载和处理;
  • 图片的答案存储在服务器端的数据库里;
  • 很多验证码都有时间限制;

我们通过一个在线的带验证码的评论表单 http://www.pythonscraping.com/humans-only ,来演示如何使用机器人破解验证码。

实现代码如下:

# encoding=utf8
from urllib.request import urlretrieve
from urllib.request import urlopen
from bs4 import BeautifulSoup
import subprocess
import requests
from PIL import Image
from PIL import ImageOps


def cleanImage(imagePath):
    image = Image.open(imagePath)
    image = image.point(lambda x: 0 if x <143 else 255)
    borderImage = ImageOps.expand(image, border=20, fill='white')
    borderImage.save(imagePath)


html = urlopen('http://www.pythonscraping.com/humans-only')
bsObj = BeautifulSoup(html,"html.parser")

imageLocation = bsObj.find("img",{'title':"Image CAPTCHA"})["src"]
formBuildId = bsObj.find("input",{"name":"form_build_id"})["value"]
captchaSid = bsObj.find("input",{"name":"captcha_sid"})["value"]
captchaToken = bsObj.find("input",{"name":"captcha_token"})["value"]

captchaUrl = "http://pythonscraping.com"+imageLocation
urlretrieve(captchaUrl,"captcha.jpg")
cleanImage("captcha.jpg")
p = subprocess.Popen(["D:\\Program Files\\Tesseract-OCR\\tesseract.exe","captcha.jpg","captcha"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p.wait()
f = open("captcha.txt","r")

captchaResponse = f.read().replace(" ","").replace("\n","")
print ("Captcha solution attempt: "+captchaResponse)

if len(captchaResponse) == 5:
    params = {"captcha_token":captchaToken,"captcha_sid":captchaSid,
              "form_id":"comment_node_page_form","form_build_id":formBuildId,
              "captcha_response":captchaResponse,"name":"Ryan Mitchell",
              "subject":"I come to seek the Grail",
              "comment_body[und][0][value]":
              "...and I am definitely not a bot"}
    r = requests.post ("http://www.pythonscraping.com/comment/reply/10",data=params)
    responseObj = BeautifulSoup(r.text)
    if responseObj.find("div",{"class":"messages"}) is not None:
        print(responseObj.find("div",{"class":"messages"}).get_text())
    else:
        print ("There was a problem reading the CAPTCHA correctly!")

最终输出结果如下:







参考资料




1、https://www.w3school.com.cn/xpath/xpath_intro.asp

2、https://github.com/tesseract-ocr/tesseract/wiki3

3、https://www.python.org/

4、《Web Scraping with Python》





唯科普 | 《数据采集》目录

A.K.A "小白终结者"系列

第1篇、初识网络通信

第2篇、来点更精彩的正则表达式吧

第3篇、多种数据采集方式

第4篇、让我们加入点API

第5篇、数据的存储

第6篇、文档读取

第7篇、数据清洗

第8篇、自然语言处理之概括数据(上篇)

第8篇、自然语言处理之马尔可夫模型(中篇)

第8篇、自然语言处理之六度分割终极篇(下篇)

第9篇、穿越网页表单与登录窗口的采集

第10篇、关于数据的采集姿势

第11篇、图像识别与文字处理

第12篇、避开采集的陷阱

第13篇、用自动化程序测试网站

第14篇、远程采集




精彩原创文章投稿有惊喜!

欢迎投稿!

VSRC欢迎精品原创类文章投稿,优秀文章一旦采纳发布,将为您准备的丰富奖金税后1000元现金或等值礼品,上不封顶!如若是安全文章连载,奖金更加丰厚,税后10000元或等值礼品,上不封顶!还可领取精美礼品!可点击“阅读原文”了解规则。(最终奖励以文章质量为准。活动最终解释权归VSRC所有)



我们聆听您宝贵建议


不知道,大家都喜欢阅读哪些类型的信息安全文章?

不知道,大家都希望我们更新关于哪些主题的干货?

现在起,只要您有任何想法或建议,欢迎直接回复本公众号留言!

精彩留言互动的热心用户,将有机会获得VSRC赠送的精美奖品一份!

同时,我们也会根据大家反馈的建议,选取热门话题,进行原创发布!


点击阅读原文进入   【VSRC征稿】宅家副业攻略请查收!



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接