基于Selenium与图像识别的百度指数爬虫

来源:互联网 发布:flash cc mac中文版 编辑:程序博客网 时间:2024/06/13 18:48

前言

在参与一个项目的时候,得到了这样一个需求,需要我用爬虫爬取某个关键词的百度指数,而当我打开网址后http://index.baidu.com/,简单登陆输入关键词后,发现事情并不那么简单。
这里写图片描述
表面上看,这里只需要模拟鼠标操作,然后读取弹出的每一个ViewBox的数据便大功告成了。但百度不会让你那么简单获取数据。
这里写图片描述
通过这张图我们很开心地发现,百度指数具体的数字竟然是图片!!!每一个数字竟然都是一个图片!!!!显然,常规的思路已经无法驾驭百度指数了,在经过综合考虑过后,我决定采用Python的图像识别包来识别并爬取百度指数。

主要技术介绍

Selenium

Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。它可以最大限度地模拟浏览器操作,每运行一个Selenium程序就会打开一个浏览器。
在本次数据采集工作中我们最为核心的是采用了ActionChains这个类,实现了模拟鼠标的移动。每次移动的距离就是从一天到下一天的距离。

 ActionChains(browser).move_to_element_with_offset(xoyelement, x_0, y_0).perform()

Pytesseract

而在获取到图像数据后,我们使用Python一个常用的图像识别包完成了图像数据向数字数据的转换。

 image = Image.open(path + "/zoom/" + printString)        code = pytesseract.image_to_string(image)

Pytesseract的安装

 sudo apt-get install tesseract-ocr sudo apt-get install python-imaging sudo pip install pytesseract

流程介绍与代码分析

此处仅摘取部分重要代码

登陆

在登陆方面我没有下太大功夫,甚至没有实现自动化,因为百度指数在爬取的过程中不会出现需要重新登陆的情况,故用一个input()函数让程序暂停会儿,登陆后输入1便可。

#百度指数网站url = "http://index.baidu.com/"browser = webdriver.Chrome()browser.get(url)# 点击网页的登录按钮  browser.find_element_by_xpath("//ul[@class='usernav']/li[4]").click()# 完成登陆后在控制台输入1jud=input("登录好后输入1")while 1:   if jud==1:       break

输入关键词并搜索

# 清空网页输入框browser.find_element_by_id("schword").clear()# 写入需要搜索的百度指数      browser.find_element_by_id("schword").send_keys(name)# 点击搜索browser.find_element_by_id("searchWords").click()

搜索ViewBox的位置并获取坐标

#找到ViewBoximgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')#定位ViewBoxlocations = imgelement.location

保存网页截图并截取ViewBox中的指数图片

#确定截图范围rangle = (int(int(locations['x'])), int(int(locations['y'])),              int(int(locations['x'])+100) ,              int(int(locations['y'])) + 80)#保存整体网页截图browser.save_screenshot(str(path) + "/raw/" + printString + ".png")#打开网页截图img = Image.open(str(path) + "/raw/" + printString + ".png")#截取ViewBoxjpg = img.crop(rangle)

放大并识别图片

#打开截取的图片jpgzoom = Image.open(str(imgpath))(x, y) = jpgzoom.size#设置放大倍数x_s = 60 * 10y_s = 20 * 10#放大图片并保存out = jpgzoom.resize((x_s, y_s), Image.ANTIALIAS)out.save(path + "/zoom/" + printString, 'jpeg', quality=95)#读取待识别的图片image = Image.open(path + "/zoom/" + printString)code = pytesseract.image_to_string(image)

错误处理

由于不可抗的因素,有些时候鼠标移动时候不一定会弹出ViewBox,这会导致空指针错误,故在截图的时候需要先做ViewBox是否Exist的判断。为了优化该问题,我们也可以写一个循环,当ViewBox不出现的时候不断循环重复鼠标的操作。

cot=0while (ExistBox(browser)==False):        cot+=1 ActionChains(browser).move_to_element_with_offset(xoyelement, x_0, y_0).perform()    if ExistBox(browser)==True:          break    if cot==6:          return None

图像识别包始终会存在错误,故有可能有一些普遍的识别错误,故可以对识别得到的数字做一个简单的替换处理

dealcode = code.replace("S", '5').replace(" ", "").replace(",", "").replace("E", "8").replace(".", ""). \            replace("'", "").replace(u"‘", "").replace("B", "8").replace("\"", "").replace("I", "1").replace(            "i", "").replace("-", ""). \replace("$", "8").replace(u"’", "").strip()

以上便是本博客的全部内容

本博客主要介绍的是百度指数爬虫主要涉及的几个模块,通过设计拼凑循环可以完成更多的任务。
以下的网址是我的一个电影百度指数查询项目,它实现了从数据库里面逐行读取电影名,并且按日期获取电影上映前后一个月百度指数并保存到数据库的功能。
https://github.com/TerenceLiu2/Crawls/blob/master/BaiduIndexCrawl/BaiduIndexCrawl.py