详解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中的实例方法、静态方法、类方法、类变量和实例变量浅析
Apr 26 Python
Python random模块(获取随机数)常用方法和使用例子
May 13 Python
python检查序列seq是否含有aset中项的方法
Jun 30 Python
Python对象类型及其运算方法(详解)
Jul 05 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
Jul 06 Python
Django2.1集成xadmin管理后台所遇到的错误集锦(填坑)
Dec 20 Python
浅谈Python批处理文件夹中的txt文件
Mar 11 Python
详解python中init方法和随机数方法
Mar 13 Python
在Python中获取操作系统的进程信息
Aug 27 Python
Python 实现使用空值进行赋值 None
Mar 12 Python
如何通过python计算圆周率PI
Nov 11 Python
pymysql模块使用简介与示例
Nov 17 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
PHP实现即时输出、实时输出内容方法
2015/05/27 PHP
详解WordPress中用于合成数组的wp_parse_args()函数
2015/12/18 PHP
Laravel框架中VerifyCsrfToken报错问题的解决
2017/08/30 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
PHP实现数据四舍五入的方法小结【4种方法】
2019/03/27 PHP
在Laravel 中实现是否关注的示例
2019/10/22 PHP
分享十五个最佳jQuery 幻灯插件和教程
2010/03/27 Javascript
jQuery - css() 方法示例详解
2014/01/16 Javascript
Javascript 按位取反运算符 (~)
2014/02/04 Javascript
JS实现CheckBox复选框全选全不选功能
2015/05/06 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
IntersectionObserver实现图片懒加载的示例
2017/09/29 Javascript
微信小程序支付之c#后台实现方法
2017/10/19 Javascript
动态Axios的配置步骤详解
2018/01/12 Javascript
JS实现百度网盘任意文件强制下载功能
2018/08/31 Javascript
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
js实现简易计算器小功能
2020/11/18 Javascript
解决基于 keep-alive 的后台多级路由缓存问题
2020/12/23 Javascript
合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友
2009/04/09 Python
Python中bisect的用法
2014/09/23 Python
Python3 实现随机生成一组不重复数并按行写入文件
2018/04/09 Python
python多继承(钻石继承)问题和解决方法简单示例
2019/10/21 Python
利用PyQt中的QThread类实现多线程
2020/02/18 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
Python实现将元组中的元素作为参数传入函数的操作
2020/06/05 Python
pycharm中leetcode插件使用图文详解
2020/12/07 Python
html5 音乐播放器 audio 标签使用概述
2013/07/15 HTML / CSS
船餐厅和泰晤士河餐饮游轮:Bateaux London
2018/03/19 全球购物
空字符串(“”)和null的区别
2012/11/13 面试题
高中军训第一天感言
2014/03/06 职场文书
融资租赁计划书
2014/04/29 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书
深入理解redis中multi与pipeline
2021/06/02 Redis