详解python3百度指数抓取实例

作者:TTyb 时间:2022-01-11 03:06:59 

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

前言:

土福曾说,百度指数很难抓,在淘宝上面是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://www.jb51.net/article/92287.htm

selenium用法请参考:https://www.jb51.net/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

来源:http://www.cnblogs.com/TTyb/p/6051366.html

标签:抓取,百度指数,python
0
投稿

猜你喜欢

  • Python中使用threading.Event协调线程的运行详解

    2023-08-05 04:39:05
  • Python编程matplotlib绘图挑钻石seaborn小提琴和箱线图

    2022-03-06 20:08:29
  • 详解使用vue-router进行页面切换时滚动条位置与滚动监听事件

    2024-05-08 09:34:39
  • PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式

    2024-04-10 10:56:49
  • 使用Vue-router二级路由跳转另一条路由下的子级

    2024-05-09 09:52:07
  • Windows下pycharm安装第三方库失败(通用解决方案)

    2022-06-07 22:54:37
  • JavaScript图片放大镜效果

    2009-10-19 22:15:00
  • python typing模块--类型提示支持

    2023-11-11 16:47:27
  • 使用wxpy实现自动发送微信消息功能

    2022-04-01 21:16:06
  • appium测试之APP元素定位及基本工具介绍

    2021-09-24 20:51:47
  • 一文教会你如何运行vue项目

    2024-05-28 15:54:33
  • python操作oracle的完整教程分享

    2023-08-28 01:18:49
  • Python配置虚拟环境图文步骤

    2023-10-13 01:37:40
  • Django实现发送邮件功能

    2021-05-13 10:25:44
  • Python是什么 Python的用处

    2021-12-20 05:55:37
  • JS高阶函数原理与用法实例分析

    2024-05-09 10:36:21
  • SqlServer Mysql数据库修改自增列的值及相应问题的解决方案

    2024-01-14 13:32:46
  • SQL语句实例说明 方便学习mysql的朋友

    2012-11-30 20:02:43
  • Python实现word2Vec model过程解析

    2023-10-07 14:22:10
  • python-pandas创建Series数据类型的操作

    2022-01-29 14:16:24
  • asp之家 网络编程 m.aspxhome.com