用图像识别做爬虫居然这么爽——下篇

欢迎关注哈希大数据微信公众号【哈希大数据】


猫眼电影票房榜单中各电影实时票房数据和总票房数据是经过加密的,咱们直接获取不到,现在咱们就尝试采用图像识别的方法把实时票房数据和总票房数据爬下来,附带把电影主演、上映时间、宣传海报链接等信息也获取下来。

本次爬取主要流程如下:

  1. 分析网页结构
  2. 用selenium调用chromedriver去驱动chrome浏览器获取网页信息
  3. 将票房信息保存为图片,利用PIL对图片进行二值化、锐化等预处理
  4. 利用tesseract对保存的图片进行识别,得到票房数据
  5. 保存数据

接下来进行详细说明:

1. 分析网页结构

猫眼电影国内票房榜URL为:https://maoyan.com/board/1,其结构较为简答,只展示国内上线电影实时票房的前十名。

image

可爬取的字段也只有7个:目前排名、实时票房数据、总票房数据、电影名称、电影主演、上映时间、宣传海报链接,不过我们要多记录一个字段:当前时间,唯一好玩的点在于实时票房是加密的,可以让咱们试试能不能利用图像识别的方式把它搞定。

2. 获取非加密数据

这里使用的是selenium模拟的方式获取网页信息,之前也介绍过,但没用它直接解析数据,前面一般是先把网页信息获取下来,再用BeautifulSoup或PyQuery这两个解析库处理解析信息,今天咱们看看如何用其API直接获取数据:
首先得到所有内容标签:

contents_list = driver.find_elements_by_css_selector('dl.board-wrapper dd')

这里注意咱们用的是find_elements_by_css_selector,element后面加了s。如果不加s,find_element方法查找就只能得到第一个节点,加了s后可获得满足条件的所有节点,以列表类型返回。
对于标签的文本内容的获取也是非常简单,例如提取电影排名:
contents['index']= content.find_element_by_css_selector('i.board-index').text
找到标签后加.text便可获得标签内容。获取标签内属性值也很简单,例如提取电影名称: contents['title']= content.find_element_by_css_selector('img.board-img').get_attribute('alt')
找到标签后加.get_attribute('属性名称')便可获得标签内属性值。具体实例如下:

for content in contents_list:<br> &nbsp;&nbsp;&nbsp; contents['index'] = content.find_element_by_css_selector('i.board-index').text<br>; contents['image_url'] = content.find_element_by_css_selector('img.boardimg').get_attribute('src')<br>;contents['title'] = content.find_element_by_css_selector('img.boardimg').get_attribute('alt')<br> &nbsp;&nbsp;&nbsp; try:<br> contents['actor'] = content.find_element_by_css_selector('p.star').text<br>; except NoSuchElementException:<br>;contents['actor'] = ''<br>; contents['time'] = content.find_element_by_css_selector('p.releasetime').t;

3. 将票房信息保存为图片,利用PIL对图片进行二值化、锐化等预处理操作
将想要获取信息的标签保存图片的一般步骤如下:
a) 截取当前窗口(selenium不能直接截取单个标签)
b) 获取标签位置坐标和标签大小
c) 利用PIL包的crop函数根据标签的坐标和大小将标签剪切保存下来

举例如下:

image

上图就是网页截图,利用save_screenshot函数可以获得当前窗口截图,咱们需要将蓝色方框内的票房数据剪切保存下来,所以我们需要它们的坐标和大小,幸运的是咱们可以利用.location和.size函数得到标签的坐标和大小,最后再利用PIL包的crop函数根据标签的坐标和大小将标签剪切保存下来。

以上步骤在截取信息在第一屏的情况很好用,但在窗口超过了一屏,且需要截取的元素在后面时,就只能另辟蹊径了。
咱们抓取猫眼电影的电影票房网页就比较长,一屏根本展示不完。当然咱们可以利用js下拉网页然后截图,这样也能将下面网页的信息截取到,但获取到的标签位置坐标的基准点在网页的左上角(如上图提示),crop函数在裁剪时以当前图片左上角为基准,所以基准不同截取出来的内容肯定不对。
在网上查到WebDriver.PhantomJS自带的方法支持对整个网页截屏,这不是太爽了,但当我用的时候又懵逼了,PhantomJS是可以截取整个网页,但截取结果是这样的:

image

尼玛要啥不给啥呀,同时程序也提示警告selenium已经不再允许使用PhantomJS了,怎么办咱们还是默默回去用chrome吧!这时突然灵光一闪,刚才不能用chrome的原因是location函数获取的标签坐标和crop函数在裁剪坐标基准不同,咱们把它调一致不就可以了(啧啧啧此处应有掌声),说干就干,这个网页上一共有10部电影我只用下拉10次就OK了,所以这里咱们来个for循环,window.scrollTo函数用了下拉网页,它有两个参数第一个是参数代表横向拖动像素数,第二个代表纵向拖动像素数。可是每次下拉多少呢?270px(像素),
咦你咋知道?
来来来告诉大家一个小技巧咱们用微信截图是它会显示截图图片大小,对本实例咱们每次下拉两个电影票房之间的长度就好,如下图其长度为270px。

image

这样应该是能得到每个票房数据标签了,在得到票房数据标签后咱们还要进行一下图片预处理(二值化,锐化),最后将标签保存下来,部分代码如下:

length = n*270driver.execute_script('window.scrollTo(0, {}*270)'.format(n))# 保存当前窗口为图片driver.save_screenshot('b.png')# time.sleep(2)# 定位div地址location = div.location# print(location)# 得到div尺寸size = div.size# print(size)left = location['x']top = location['y'] - lengthright = location['x'] + size['width']bottom = location['y'] + size['height'] - length

4. 利用tesseract对保存的图片进行识别,得到票房数据
原始票房数据图片:

image

预处理后的票房数据图片:

image

对处理后的图片进行利用tesseract进行识别处理,部分代码如下:

# 调用tesseract进行文字数字识别,目前对于浅颜色的字体识别率较低,若想提高识别率需要对图片做预处理os.system('echo off')#关闭命令行窗口运行命令的显示os.system('tesseract' + ' ' + filename + ' ' + output + ' ' + '-l num+chi_tra') #默认已配置好系统变量time.sleep(2)f = open(output + ".txt", encoding='utf-8')try:    t = f.readlines()[0]

目前在没有去训练自己的数据识别包,直接利用tesseract的现有数据包,通过多次试验对实时票房的识别率已达到97%以上,由于总票房字体颜色太浅,且字体较小目前识别率还比较低在60%左右。得到的数据具体如下图所示:

image

本次初次尝试利用图像识别解决爬虫与到的问题,感觉确实比较好玩,目前获取标签图片的流程已经打通,但图像预处理和图像识别部分还有大量工作要做,目前是采用第三方软件Tesseract-OCR进行的识别,后面一方面会继续研究Tesseract-OCR,另一方面也会尝试利用深度学习的方法提高图片文字的识别精度

image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容