当前位置:首页 > 科技 > 正文

抓取百度指数引发的图像数字识别

作者介绍:

叶成,数据分析师,就职于易居中国,热爱数据分析和挖掘工作,擅长使用倒腾数据。

前言

学习爬虫也有段时间了,闲着无趣,想找点项目练练手,于是乎通过顺祥老师介绍,接到了一个关于百度指数的爬虫需求。(百度指数可以反映一个词在一段时间内的搜索热度,不知道百度指数的同学们可以自行百度)。好的,话不多说,开始我们的项目。

百度指数页面

百度指数_指数百度com_三倍做空纳斯达克指数百度

输入查询的关键字

百度指数_指数百度com_三倍做空纳斯达克指数百度

嗯?跳转到了登陆界面!(赶紧拿出小本本记下,这里需要登陆)。

登陆后的展现

三倍做空纳斯达克指数百度_百度指数_指数百度com

心中窃喜,脑子里满是抓包分析,模拟请求,获取指数,!!!然而事实并没那么简单,根据爬虫的套路,需要查看属性(在上图中右键检查,找到文件):

百度指数_指数百度com_三倍做空纳斯达克指数百度

正常来说这里的json文件中应该就有我们需要的文本内容,然而打开后发现它是一张图片,而且还是一张拼图,如下图所示:

并且这个图片链接包含了三个参数,如下图所示(黄色标出):

指数百度com_百度指数_三倍做空纳斯达克指数百度

看得脑壳都大了,先不说怎么分析加密参数,就算是破解了拿到图片链接,也无法直接取出需要的数字,因为还需要进行图像识别…沉思中…没办法,打算曲线救国,我们直接模拟鼠标移动,然后截取悬浮的黑框图片,再进行图像识别,得到百度指数。新的思路就是这样,开搞。具体步骤如下:

browser= webdriver.Chrome('C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe')
browser.get('http://index.baidu.com/?from=pinzhuan')
browser.find_element_by_id("schword").clear()
browser.find_element_by_id("schword").send_keys(keys)
browser.find_element_by_id("searchWords").click()
time.sleep(2)
e1 = browser.find_element_by_id("TANGRAM_12__userName")
e1.send_keys("百度账号")
e2 = browser.find_element_by_id("TANGRAM_12__password")
e2.send_keys("密码")
e3 = browser.find_element_by_id("TANGRAM_12__submit")
e3.click()

我们使用驱动谷歌浏览器,定位到输入框,清空并输入关键词,跳转登陆页面后在登陆百度指数。

browser.maximize_window()
xoyelement = browser.find_elements_by_css_selector("#trend rect")[2]
x_0=1

for i in range(30):        ActionChains(browser).move_to_element_with_offset(xoyelement, x_0, 0).perform()        time.sleep(2)        display = browser.find_element_by_xpath("//*[@id='viewbox']").get_attribute("style")        style = re.findall('display: (.*?); ',display)[0]        print(style)        #browser.execute_script(js)        cot=0        while style == 'none':            ActionChains(browser).move_to_element_with_offset(xoyelement, x_0+ random.uniform(0,3), 0).perform()            display = browser.find_element_by_xpath("//*[@id='viewbox']").get_attribute("style")            style = re.findall('display: (.*?); ',display)[0]            browser.execute_script(js)            time.sleep(1)
           if style == 'block':                print('viewbox已找到')
               break            cot = cot +1            if cot >200:                print('未找到viewbox')                
               break        time.sleep(1)        browser.save_screenshot("E:/downloads/%s.png" %i)

这当中的核心是().(, x_0, 0).()。这个是用来确定鼠标的悬浮位置,我们先是通过css定位到,然后通过(, x_0, 0),确定偏移的位置,我们这里使x_0初始值为1,是因为发现为0时数值不出现。

指数百度com_百度指数_三倍做空纳斯达克指数百度

下图中显示的是, 为了防止鼠标移动时没有的情况,我们通过判断样式是否为隐藏来确定是否出现。

要确保出现后才能进行屏幕截图。

imgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')
locations = imgelement.location
sizes = imgelement.size
add_length = (len(keys) - 2) * sizes['width'] / 15scroll = browser.execute_script("return window.scrollY;")
top = locations['y'] - scroll
rangle = (int(locations['x'] + sizes['width'] / 4 + add_length), int(top + sizes['height'] / 2),
       int(locations['x'] + sizes['width'] * 2 / 3), int(top + sizes['height']))
img = Image.open("E:/downloads/%s.png"%i)
jpg = img.crop(rangle)
jpg.save('E:/downloads/crop%s.jpg' %i)

先定位到位置,然后我们构建了一个关键字长度的公式,以及的范围的公式,这当中绝大部分参考百度,感谢百度!通过上面的布置,可以把百度指数的图片给下载下来,接下来的工作就是从这些图片中进行数字的识别。

三倍做空纳斯达克指数百度_百度指数_指数百度com

index = []
for m in range(30):    jpgzoom = Image.open("E:/downloads/crop%s.jpg" %m)    (x, y) = jpgzoom.size    x_s = 2*x    y_s = 2*y    out = jpgzoom.resize((x_s, y_s), Image.ANTIALIAS)    out.save('E:/downloads/zoom%s.jpg' %m, quality=95)    image = Image.open('E:/downloads/zoom%s.jpg' %m)    code = pytesseract.image_to_string(image)
   if code:        code=code.replace('.','').replace(',','')        index.append(code)
   else:        code=''        index.append(code)

with
open ('E:/downloads/index.txt','w') as f:
   for item in index:        f.write(item + '\n')

这里的主要思想是:先将图片放大一倍从而提高识别率,然后用这个模块进行识别,因为我们截取的数字在图片中十分‘干净’,无需做什么处理,很开心,只需对识别结果中的 ’,’ 或者是 ’.’ 去除即可。

指数百度com_三倍做空纳斯达克指数百度_百度指数

结语

OK,关于百度指数数据抓取的分享就到这里,欢迎各位网友投稿和交流。如需完整代码,可关注公众号并回复“百度指数”。

你可能想看:

有话要说...

取消
扫码支持 支付码