详解python3百度指数抓取实例


Posted in Python onDecember 12, 2016

百度指数抓取,再用图像识别得到指数

前言:

土福曾说,百度指数很难抓,在淘宝上面是20块1个关键字:

详解python3百度指数抓取实例

哥那么叼的人怎么会被他吓到,于是乎花了零零碎碎加起来大约2天半搞定,在此鄙视一下土福

安装的库很多:

谷歌图像识别tesseract-ocr

pip3 install pillow

pip3 install pyocr

selenium2.45

Chrome47.0.2526.106 m or Firebox32.0.1

chromedriver.exe

图像识别验证码请参考:https://3water.com/article/92287.htm

selenium用法请参考:https://3water.com/article/52329.htm

进入百度指数需要登陆,登陆的账号密码写在文本account里面:

详解python3百度指数抓取实例

万能登陆代码如下:

# 打开浏览器
def openbrowser():
  global browser

  # https://passport.baidu.com/v2/?login
  url = "https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F"
  # 打开谷歌浏览器
  # Firefox()
  # Chrome()
  browser = webdriver.Chrome()
  # 输入网址
  browser.get(url)
  # 打开浏览器时间
  # print("等待10秒打开浏览器...")
  # time.sleep(10)

  # 找到id="TANGRAM__PSP_3__userName"的对话框
  # 清空输入框
  browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
  browser.find_element_by_id("TANGRAM__PSP_3__password").clear()

  # 输入账号密码
  # 输入账号密码
  account = []
  try:
    fileaccount = open("../baidu/account.txt")
    accounts = fileaccount.readlines()
    for acc in accounts:
      account.append(acc.strip())
    fileaccount.close()
  except Exception as err:
    print(err)
    input("请正确在account.txt里面写入账号密码")
    exit()
  browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
  browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])

  # 点击登陆登陆
  # id="TANGRAM__PSP_3__submit"
  browser.find_element_by_id("TANGRAM__PSP_3__submit").click()

  # 等待登陆10秒
  # print('等待登陆10秒...')
  # time.sleep(10)
  print("等待网址加载完毕...")

  select = input("请观察浏览器网站是否已经登陆(y/n):")
  while 1:
    if select == "y" or select == "Y":
      print("登陆成功!")
      print("准备打开新的窗口...")
      # time.sleep(1)
      # browser.quit()
      break

    elif select == "n" or select == "N":
      selectno = input("账号密码错误请按0,验证码出现请按1...")
      # 账号密码错误则重新输入
      if selectno == "0":

        # 找到id="TANGRAM__PSP_3__userName"的对话框
        # 清空输入框
        browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
        browser.find_element_by_id("TANGRAM__PSP_3__password").clear()

        # 输入账号密码
        account = []
        try:
          fileaccount = open("../baidu/account.txt")
          accounts = fileaccount.readlines()
          for acc in accounts:
            account.append(acc.strip())
          fileaccount.close()
        except Exception as err:
          print(err)
          input("请正确在account.txt里面写入账号密码")
          exit()

        browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
        browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])
        # 点击登陆sign in
        # id="TANGRAM__PSP_3__submit"
        browser.find_element_by_id("TANGRAM__PSP_3__submit").click()

      elif selectno == "1":
        # 验证码的id为id="ap_captcha_guess"的对话框
        input("请在浏览器中输入验证码并登陆...")
        select = input("请观察浏览器网站是否已经登陆(y/n):")

    else:
      print("请输入“y”或者“n”!")
      select = input("请观察浏览器网站是否已经登陆(y/n):")

登陆的页面:

详解python3百度指数抓取实例

登陆过后需要打开新的窗口,也就是打开百度指数,并且切换窗口,在selenium用:

# 新开一个窗口,通过执行js来新开一个窗口
js = 'window.open("http://index.baidu.com");'
browser.execute_script(js)
# 新窗口句柄切换,进入百度指数
# 获得当前打开所有窗口的句柄handles
# handles为一个数组
handles = browser.window_handles
# print(handles)
# 切换到当前最新打开的窗口
browser.switch_to_window(handles[-1])

清空输入框,构造点击天数:

# 清空输入框
browser.find_element_by_id("schword").clear()
# 写入需要搜索的百度指数
browser.find_element_by_id("schword").send_keys(keyword)
# 点击搜索
# <input type="submit" value="" id="searchWords" onclick="searchDemoWords()">
browser.find_element_by_id("searchWords").click()
time.sleep(2)
# 最大化窗口
browser.maximize_window()
# 构造天数
sel = int(input("查询7天请按0,30天请按1,90天请按2,半年请按3:"))
day = 0
if sel == 0:
  day = 7
elif sel == 1:
  day = 30
elif sel == 2:
  day = 90
elif sel == 3:
  day = 180
sel = '//a[@rel="' + str(day) + '"]'
browser.find_element_by_xpath(sel).click()
# 太快了
time.sleep(2)

天数也就是这里:

详解python3百度指数抓取实例

找到图形框:

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

图形框就是:

详解python3百度指数抓取实例

根据坐标点的不同构造偏移量:

详解python3百度指数抓取实例

选取7天的坐标来观察:

第一个点的横坐标为1031.66666

第二个点的横坐标为1234

详解python3百度指数抓取实例

所以7天两个坐标之间的差为:202.33,其他的天数类似

用selenium库来模拟鼠标滑动悬浮:

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(browser).move_to_element_with_offset(xoyelement,x_0,y_0).perform()

但是这样子确定的点指出是在这个位置:

详解python3百度指数抓取实例

也就是矩形的左上角,这里是不会加载js显示弹出框的,所以要给横坐标+1:

x_0 = 1
y_0 = 0

写个按照天数的循环,让横坐标累加:

# 按照选择的天数循环
for i in range(day):
  # 构造规则
  if day == 7:
    x_0 = x_0 + 202.33
  elif day == 30:
    x_0 = x_0 + 41.68
  elif day == 90:
    x_0 = x_0 + 13.64
  elif day == 180:
    x_0 = x_0 + 6.78

鼠标横移时会弹出框,在网址里面找到这个框:

详解python3百度指数抓取实例

selenium自动识别之...:

# <div class="imgtxt" style="margin-left:-117px;"></div>
imgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')

并且确定这个框的大小位置:

# 找到图片坐标
locations = imgelement.location
print(locations)
# 找到图片大小
sizes = imgelement.size
print(sizes)
# 构造指数的位置
rangle = (int(locations['x']), int(locations['y']), int(locations['x'] + sizes['width']),
     int(locations['y'] + sizes['height']))

截取的图形为:

详解python3百度指数抓取实例

下面的思路就是:

1.将整个屏幕截图下来

2.打开截图用上面得到的这个坐标rangle进行裁剪

但是最后裁剪出来的是上面的那个黑框,我想要的效果是:

 详解python3百度指数抓取实例

所以要对rangle进行计算,但是我懒,忽略了搜索词的长度,直接暴力的写成:

# 构造指数的位置
rangle = (int(locations['x'] + sizes['width']/3), int(locations['y'] + sizes['height']/2), int(locations['x'] + sizes['width']*2/3),
     int(locations['y'] + sizes['height']))

这个写法最终不太好,最起码要对keyword的长度进行判断,长度过长会导致截图坐标出现偏差,反正我知道怎么做,就是不写出来给你们看!

后面的完整代码是:

# <div class="imgtxt" style="margin-left:-117px;"></div>
imgelement = browser.find_element_by_xpath('//div[@id="viewbox"]')
# 找到图片坐标
locations = imgelement.location
print(locations)
# 找到图片大小
sizes = imgelement.size
print(sizes)
# 构造指数的位置
rangle = (int(locations['x'] + sizes['width']/3), int(locations['y'] + sizes['height']/2), int(locations['x'] + sizes['width']*2/3),
     int(locations['y'] + sizes['height']))
# 截取当前浏览器
path = "../baidu/" + str(num)
browser.save_screenshot(str(path) + ".png")
# 打开截图切割
img = Image.open(str(path) + ".png")
jpg = img.crop(rangle)
jpg.save(str(path) + ".jpg")

但是后面发现裁剪的图片太小,识别精度太低,所以需要对图片进行扩大:

# 将图片放大一倍
# 原图大小73.29
jpgzoom = Image.open(str(path) + ".jpg")
(x, y) = jpgzoom.size
x_s = 146
y_s = 58
out = jpgzoom.resize((x_s, y_s), Image.ANTIALIAS)
out.save(path + 'zoom.jpg', 'png', quality=95)

原图大小请 右键->属性->详细信息 查看,我的是长73像素,宽29像素

最后就是图像识别

# 图像识别
index = []
image = Image.open(str(path) + "zoom.jpg")
code = pytesseract.image_to_string(image)
if code:
  index.append(code)

最后效果图:

详解python3百度指数抓取实例

详解python3百度指数抓取实例

源码下载:demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python编程入门的一些基本知识
May 13 Python
python中私有函数调用方法解密
Apr 29 Python
Python 获得命令行参数的方法(推荐)
Jan 24 Python
啥是佩奇?使用Python自动绘画小猪佩奇的代码实例
Feb 20 Python
Python利用scapy实现ARP欺骗的方法
Jul 23 Python
python基础 range的用法解析
Aug 23 Python
python自动化工具之pywinauto实例详解
Aug 26 Python
python实现输出一个序列的所有子序列示例
Nov 18 Python
浅谈Python中range与Numpy中arange的比较
Mar 11 Python
解决Django中checkbox复选框的传值问题
Mar 31 Python
浅谈Python3多线程之间的执行顺序问题
May 02 Python
python 判断字符串当中是否包含字符(str.contain)
Jun 01 Python
python实现多线程抓取知乎用户
Dec 12 #Python
浅谈Python类里的__init__方法函数,Python类的构造函数
Dec 10 #Python
详解常用查找数据结构及算法(Python实现)
Dec 09 #Python
详解Python装饰器由浅入深
Dec 09 #Python
python利用正则表达式提取字符串
Dec 08 #Python
基于python的七种经典排序算法(推荐)
Dec 08 #Python
Python序列操作之进阶篇
Dec 08 #Python
You might like
外媒评选出10支2020年最受欢迎的Dota2战队
2021/03/05 DOTA
使用 php4 加速 web 传输
2006/10/09 PHP
PHP中使用gettext来支持多语言的方法
2011/05/02 PHP
PHP截断标题且兼容utf8和gb2312编码
2013/09/22 PHP
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
一个经典的PHP验证码类分享
2014/11/18 PHP
解读PHP中的垃圾回收机制
2015/08/10 PHP
php 流程控制switch的简单实例
2016/06/07 PHP
TP - 比RBAC更好的权限认证方式(Auth类认证)
2021/03/09 PHP
让innerHTML的脚本也可以运行起来
2006/07/01 Javascript
简略的前端架构心得&amp;&amp;基于editor为例子的编码小技巧
2010/11/25 Javascript
第四章之BootStrap表单与图片
2016/04/25 Javascript
基于BootStrap Metronic开发框架经验小结【五】Bootstrap File Input文件上传插件的用法详解
2016/05/12 Javascript
bootstrap modal弹出框的垂直居中
2016/12/14 Javascript
js的三种继承方式详解
2017/01/21 Javascript
基于vue 动态加载图片src的解决方法
2018/02/05 Javascript
关于Webpack dev server热加载失败的解决方法
2018/02/22 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
2018/08/24 Javascript
jquery多级树形下拉菜单的实例代码
2019/07/09 jQuery
vue移动端的左右滑动事件详解
2020/06/17 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
2020/07/26 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
Python  __getattr__与__setattr__使用方法
2008/09/06 Python
python通过ssh-powershell监控windows的方法
2015/06/02 Python
Python序列操作之进阶篇
2016/12/08 Python
python 实现tar文件压缩解压的实例详解
2017/08/20 Python
基于Django用户认证系统详解
2018/02/21 Python
numpy中的delete删除数组整行和整列的实例
2018/05/09 Python
英国领先的电子、技术和办公用品购物网站:Ebuyer
2018/04/04 全球购物
Melissa鞋马来西亚官方网站:MDreams马来西亚
2018/04/05 全球购物
类、抽象类、接口的差异
2016/06/13 面试题
放飞梦想演讲稿
2014/05/05 职场文书
2014年秋季新学期寄语
2014/08/02 职场文书
2014年护士长工作总结
2014/11/11 职场文书
公司更名通知函
2015/04/24 职场文书
新手必备之MySQL msi版本下载安装图文详细教程
2021/05/21 MySQL