当前位置:Gxlcms > Python > 详解python3百度指数抓取实例

详解python3百度指数抓取实例

时间:2021-07-01 10:21:17 帮助过:65人阅读

本篇文章主要介绍了python3百度指数抓取,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。

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

前言:

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

详解python3百度指数抓取实例

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

安装的库很多:

  1. 谷歌图像识别tesseract-ocr
  2. pip3 install pillow
  3. pip3 install pyocr
  4. selenium2.45
  5. Chrome47.0.2526.106 m or Firebox32.0.1
  6. chromedriver.exe

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

详解python3百度指数抓取实例

万能登陆代码如下:

  1. # 打开浏览器
  2. def openbrowser():
  3. global browser
  4. # http://www.gxlcms.com/
  5. url = "https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F"
  6. # 打开谷歌浏览器
  7. # Firefox()
  8. # Chrome()
  9. browser = webdriver.Chrome()
  10. # 输入网址
  11. browser.get(url)
  12. # 打开浏览器时间
  13. # print("等待10秒打开浏览器...")
  14. # time.sleep(10)
  15. # 找到id="TANGRAM__PSP_3__userName"的对话框
  16. # 清空输入框
  17. browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
  18. browser.find_element_by_id("TANGRAM__PSP_3__password").clear()
  19. # 输入账号密码
  20. # 输入账号密码
  21. account = []
  22. try:
  23. fileaccount = open("../baidu/account.txt")
  24. accounts = fileaccount.readlines()
  25. for acc in accounts:
  26. account.append(acc.strip())
  27. fileaccount.close()
  28. except Exception as err:
  29. print(err)
  30. input("请正确在account.txt里面写入账号密码")
  31. exit()
  32. browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
  33. browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])
  34. # 点击登陆登陆
  35. # id="TANGRAM__PSP_3__submit"
  36. browser.find_element_by_id("TANGRAM__PSP_3__submit").click()
  37. # 等待登陆10秒
  38. # print('等待登陆10秒...')
  39. # time.sleep(10)
  40. print("等待网址加载完毕...")
  41. select = input("请观察浏览器网站是否已经登陆(y/n):")
  42. while 1:
  43. if select == "y" or select == "Y":
  44. print("登陆成功!")
  45. print("准备打开新的窗口...")
  46. # time.sleep(1)
  47. # browser.quit()
  48. break
  49. elif select == "n" or select == "N":
  50. selectno = input("账号密码错误请按0,验证码出现请按1...")
  51. # 账号密码错误则重新输入
  52. if selectno == "0":
  53. # 找到id="TANGRAM__PSP_3__userName"的对话框
  54. # 清空输入框
  55. browser.find_element_by_id("TANGRAM__PSP_3__userName").clear()
  56. browser.find_element_by_id("TANGRAM__PSP_3__password").clear()
  57. # 输入账号密码
  58. account = []
  59. try:
  60. fileaccount = open("../baidu/account.txt")
  61. accounts = fileaccount.readlines()
  62. for acc in accounts:
  63. account.append(acc.strip())
  64. fileaccount.close()
  65. except Exception as err:
  66. print(err)
  67. input("请正确在account.txt里面写入账号密码")
  68. exit()
  69. browser.find_element_by_id("TANGRAM__PSP_3__userName").send_keys(account[0])
  70. browser.find_element_by_id("TANGRAM__PSP_3__password").send_keys(account[1])
  71. # 点击登陆sign in
  72. # id="TANGRAM__PSP_3__submit"
  73. browser.find_element_by_id("TANGRAM__PSP_3__submit").click()
  74. elif selectno == "1":
  75. # 验证码的id为id="ap_captcha_guess"的对话框
  76. input("请在浏览器中输入验证码并登陆...")
  77. select = input("请观察浏览器网站是否已经登陆(y/n):")
  78. else:
  79. print("请输入“y”或者“n”!")
  80. select = input("请观察浏览器网站是否已经登陆(y/n):")

登陆的页面:

详解python3百度指数抓取实例

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

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

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

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

天数也就是这里:

详解python3百度指数抓取实例

找到图形框:

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

图形框就是:

详解python3百度指数抓取实例

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

详解python3百度指数抓取实例

选取7天的坐标来观察:

第一个点的横坐标为1031.66666

第二个点的横坐标为1234

详解python3百度指数抓取实例

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

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

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

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

详解python3百度指数抓取实例

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

  1. x_0 = 1
  2. y_0 = 0

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

  1. # 按照选择的天数循环
  2. for i in range(day):
  3. # 构造规则
  4. if day == 7:
  5. x_0 = x_0 + 202.33
  6. elif day == 30:
  7. x_0 = x_0 + 41.68
  8. elif day == 90:
  9. x_0 = x_0 + 13.64
  10. elif day == 180:
  11. x_0 = x_0 + 6.78

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

详解python3百度指数抓取实例

selenium自动识别之...:

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

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

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

截取的图形为:

详解python3百度指数抓取实例

下面的思路就是:

1.将整个屏幕截图下来

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

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

详解python3百度指数抓取实例

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

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

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

后面的完整代码是:

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

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

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

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

最后就是图像识别

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

最后效果图:

详解python3百度指数抓取实例

详解python3百度指数抓取实例


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持PHP中文网。

更多详解python3百度指数抓取实例相关文章请关注PHP中文网!

人气教程排行