最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python使用selenium登錄QQ郵箱(附帶滑動(dòng)解鎖)

 更新時(shí)間:2019年01月23日 09:35:06   作者:grant_2182967721  
這篇文章主要為大家詳細(xì)介紹了python使用selenium登錄QQ郵箱,帶滑動(dòng)解鎖登錄功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

最近因?yàn)楣ぷ餍枰?用selenium做了一個(gè)QQ郵箱的爬蟲(登錄時(shí)部分帳號(hào)要滑動(dòng)解鎖),先簡(jiǎn)單記錄一下。

這個(gè)問題先可以分為兩個(gè)部分:1.登錄帳號(hào)2.滑動(dòng)解鎖。python版本3.5.4

問題分析:登錄+滑動(dòng)解鎖

其實(shí)登錄賬號(hào)的部分本來很簡(jiǎn)單,用selenium打開QQ郵箱官網(wǎng):https://mail.qq.com 然后切換frame輸入帳號(hào)

和密碼點(diǎn)擊登錄即可,但是部分賬號(hào),或者可以說是異地登錄的QQ賬號(hào)需要滑動(dòng)解鎖驗(yàn)證碼才能繼續(xù)登錄(下圖)

看到這張圖我們應(yīng)該不難想到:

1、我們需要模擬人拖動(dòng)按鈕
2、按鈕拖動(dòng)的距離=拼圖間的距離

這個(gè)明確了之后那接下來我們先看看拼圖間的距離到底怎么算。登錄雖然不難,但還是寫一下,免得說我偷懶0.0

1.1 登錄

# coding = utf-8
from selenium import webdriver
import time
import random
from utils import DbUtil
import uuid
from selenium.webdriver import ActionChains
from PIL import Image as Im
import os
import cv2
import numpy as np
import requests
from pymongo import MongoClient

# 代碼1.1 目前只用到webdriver和time庫 其他的會(huì)在下面用到
# u 帳號(hào),p 密碼
def Email(u, p):
 # 定義QQ郵箱的登錄頁
 start_url = "https://mail.qq.com"

 # 這里我用的是火狐瀏覽器。很多人喜歡定義成driver 我喜歡定義成browser
 browser = webdriver.Firefox()

 # 休息2s
 time.sleep(2)

 # 使用火狐瀏覽器打開QQ郵箱的登錄頁
 browser.get(start_url)

 # 休息2s(這個(gè)sleep時(shí)間因網(wǎng)速而異,部分的錯(cuò)誤就是因?yàn)榫W(wǎng)站還沒打開你就開始獲取網(wǎng)頁的標(biāo)簽進(jìn)行操作,當(dāng)然就獲取不到然后報(bào)錯(cuò)了~)
 time.sleep(2)

 # 切換frame。login_frame是該登錄窗口iframe的id
 browser.switch_to.frame("login_frame")

 # 點(diǎn)擊選擇帳號(hào)密碼登錄
 browser.find_element_by_id("switcher_plogin").click()

 # 休息1s
 time.sleep(1)

 # 輸入帳號(hào) 將u填入id是u的輸入框
 browser.find_element_by_id("u").send_keys(u)
 time.sleep(1)

 # 輸入密碼 將p填入id是p的輸入框
 browser.find_element_by_id("p").send_keys(p)
 time.sleep(1)

 # 點(diǎn)擊登錄 登錄按鈕的id是login_button
 browser.find_element_by_id("login_button").click()

# main方法
if __name__ == '__main__':
 # 為了實(shí)現(xiàn)異地登錄 隨意定義一個(gè)QQ號(hào)(反正我們的目的是滑動(dòng)解鎖0.0),如果直接提示帳號(hào)密碼錯(cuò)誤沒有驗(yàn)證碼的話就再隨意編一個(gè)QQ號(hào)
 Email(u="123456789", p="abcdefg")

運(yùn)行一下 應(yīng)該就能看到我們要的滑動(dòng)驗(yàn)證碼了

1.2 獲取驗(yàn)證碼圖片

我們?cè)谶\(yùn)行完上面的代碼之后驗(yàn)證碼應(yīng)該出來了,首先我們需要將其中的拼圖和完整圖片下載下來用于后面的距離計(jì)算。
我們先F12 然后
點(diǎn)擊左側(cè)的小拼圖查看元素↓

點(diǎn)擊大拼圖查看元素↓

以上選中的這兩張圖片就是我們后面要用來計(jì)算滑動(dòng)距離的圖片

要獲取到圖片需要兩步:

1、獲取到圖片的鏈接(上面已經(jīng)能看到了)
2、根據(jù)鏈接將圖片下載到本地處理

回到剛才的代碼 我們需要先加個(gè)判斷來識(shí)別是否出現(xiàn)了滑動(dòng)驗(yàn)證碼(有的時(shí)候會(huì)直接提示帳號(hào)密碼錯(cuò)誤)
只要判斷這個(gè)"安全驗(yàn)證"的提示就可以說明是有滑動(dòng)驗(yàn)證碼的,反之沒有。

# 代碼1.1省略....↑
# 代碼1.2.1
# 判斷是否出現(xiàn)了滑動(dòng)驗(yàn)證碼
try:
 # 先切換frame回到默認(rèn)
 browser.switch_to.default_content()
 
 # 將frame切換到 login_frame(也就是之前的登錄frame)
 browser.switch_to.frame("login_frame")
 
 # 根據(jù)xpath獲取到含有安全提示的標(biāo)簽然后將其中文本獲取到打印出來 如果異常就進(jìn)except塊 說明沒有驗(yàn)證碼
 code = browser.find_element_by_xpath('//*[@id="newVcodeArea"]/div[1]/div/div[2]').text
 print(code)
except :
 print('無安全驗(yàn)證碼!')

這塊代碼寫完我們基本上實(shí)現(xiàn)了登錄判斷是否出現(xiàn)滑動(dòng)驗(yàn)證碼的功能,不多BB我們繼續(xù)↓

出現(xiàn)滑動(dòng)驗(yàn)證碼的時(shí)候我們先點(diǎn)擊刷新

此處要加入兩個(gè)方法用來解決: 下載圖片的問題計(jì)算拼圖還原的問題

我們先下載圖片到本地 然后通過處理圖片來計(jì)算拼圖還原的距離

# 代碼2
# 圖片下載到本地,返回一個(gè)本地鏈接。url 是圖片的鏈接,type區(qū)分左側(cè)小拼圖和大圖,大圖傳big,小圖傳small
def pic_download(url,type):
 url = url
 root = "D:/emils_python/pic_test/"
 # path = root + str(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))+'.png'
 path = root + type + '.png'
 try:
 if not os.path.exists(root):
 os.mkdir(root)
 if os.path.exists(path):
 os.remove(path)
 r = requests.get(url)
 r.raise_for_status()
 # 使用with語句可以不用自己手動(dòng)關(guān)閉已經(jīng)打開的文件流
 with open(path, "wb") as f: # 開始寫文件,wb代表寫二進(jìn)制文件
 f.write(r.content)
 print(f.name)
 print("下載完成")
 return f.name

 except Exception as e:
 print("獲取失敗!" + str(e))

到這里圖片下載的方法就ok了↑ 然后繼續(xù)寫計(jì)算拼圖還原的方法↓

# 代碼3
# 獲取缺口位置 small_url是小圖的路徑(本地),big_url是大圖的路徑(本地) 最后return一個(gè)計(jì)算出的距離
def get_distance(small_url,big_url):
 # 引用上面的圖片下載
 otemp = pic_download(small_url,'small')
 
 time.sleep(2)
 
 # 引用上面的圖片下載
 oblk = pic_download(big_url,'big')

 # 計(jì)算拼圖還原距離
 target = cv2.imread(otemp, 0)
 template = cv2.imread(oblk, 0)
 w, h = target.shape[::-1]
 temp = 'temp.jpg'
 targ = 'targ.jpg'
 cv2.imwrite(temp, template)
 cv2.imwrite(targ, target)
 target = cv2.imread(targ)
 target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
 target = abs(255 - target)
 cv2.imwrite(targ, target)
 target = cv2.imread(targ)
 template = cv2.imread(temp)
 result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
 x, y = np.unravel_index(result.argmax(), result.shape)
 # 缺口位置
 print((y, x, y + w, x + h))

 # 調(diào)用PIL Image 做測(cè)試
 image = Im.open(oblk)

 xy = (y + 20, x + 20, y + w - 20, x + h - 20)
 # 切割
 imagecrop = image.crop(xy)
 # 保存切割的缺口
 imagecrop.save("D:/emils_python/pic_test/new_image.jpg")
 return y

到這里計(jì)算拼圖還原的距離的方法基本上就完成了↑

有了下載圖片計(jì)算拼圖還原的方法 我們就可以直接調(diào)用get_distance方法計(jì)算拼圖還原的距離

# 代碼1.1省略....↑
# 還是代碼1.2
# 判斷是否出現(xiàn)了滑動(dòng)驗(yàn)證碼
try:
 # 先切換frame回到默認(rèn)
 browser.switch_to.default_content()
 
 # 將frame切換到 login_frame(也就是之前的登錄frame)
 browser.switch_to.frame("login_frame")
 
 # 根據(jù)xpath獲取到含有安全提示的標(biāo)簽然后將其中文本獲取到打印出來 如果異常就進(jìn)except塊 說明沒有驗(yàn)證碼
 code = browser.find_element_by_xpath('//*[@id="newVcodeArea"]/div[1]/div/div[2]').text
 print(code)
 
 # 如果后面拖動(dòng)失敗 我們就再次循環(huán) 所以用while
 while True:
 # 切換frame
 browser.switch_to.default_content()
 
 # 切換frame
 browser.switch_to.frame('login_frame')
 
 # 切換帶有刷新按鈕的frame
 browser.switch_to.frame(browser.find_element_by_xpath('//*[@id="newVcodeIframe"]/iframe'))
 
 # 點(diǎn)擊刷新 id為e_reload
 browser.find_element_by_id('e_reload').click()

 # 獲取圖片鏈接
 big_url = browser.find_element_by_id('slideBkg').get_attribute('src')
 small_url = browser.find_element_by_id('slideBlock').get_attribute('src')
 
 # 下載圖片并計(jì)算拼圖還原的距離
 y = get_distance(small_url, big_url)
 
 # 獲取當(dāng)前網(wǎng)頁鏈接,用于判斷拖動(dòng)驗(yàn)證碼后是否成功,如果拖動(dòng)后地址沒變則為失敗
 url1 = browser.current_url
 
 # 獲取藍(lán)色拖動(dòng)按鈕對(duì)象
 element = browser.find_element_by_id('tcaptcha_drag_button')
 
 # 計(jì)算distance
 distance = y * (280 / 680) - 21
 print('distance:', distance)
except :
 print('無安全驗(yàn)證碼!')

寫到這里 基本上我們可以計(jì)算出拼圖還原的距離了。
是不是開始看著覺得很有道理…突然看到最后兩行…WTF??? distance = y * (280 / 680) - 21 是什么意思?
別著急慢慢解釋…通過上面的代碼已經(jīng)知道了 y 就是圖片還原的距離,但是我們還少考慮了2點(diǎn):

1.圖片的起始位置其實(shí)不是最左側(cè),而是向右偏移了一點(diǎn)
2.我們從下載到本地的圖片尺寸是否跟網(wǎng)頁上的圖片尺寸一致 ? 答案當(dāng)然是否定的。

我們先看一下拼圖起始的位置

很清晰的能看到拼圖到左邊的有一段距離 那到底是多少呢 ? 我已經(jīng)找人用專業(yè)的工具測(cè)過了:21左右
為了好理解 我特地用手機(jī)拍了張照片又截圖下來,自己體會(huì)一下… 就是個(gè)大概的意思 為了好理解…

以上是拼圖到左側(cè)的距離 然后我們?cè)倏匆幌挛覀冊(cè)?strong>本地處理并計(jì)算的圖片尺寸和網(wǎng)頁上的圖片有什么區(qū)別

先看本地處理過后的圖片

很明顯能夠看到長(zhǎng)是680

我們?cè)倏匆幌?strong>網(wǎng)頁上的…沒錯(cuò)還是我找的人用專業(yè)工具給測(cè)的…280,笨笨的老方法幫你們理解一下

所以我們講了這么多 會(huì)發(fā)現(xiàn) :

按鈕需要滑動(dòng)的距離(網(wǎng)頁) = 拼圖的還原距離(本地圖片) * (網(wǎng)頁上的長(zhǎng)度 / 本地圖片的長(zhǎng)度) -21(多出來的起始位置)

也就是前面會(huì)讓人疑惑的 distance = y * (280 / 680) - 21 當(dāng)然 這些都因?qū)嶋H情況而定

到了這一步 可以說我們最難的部分已經(jīng)解決了

有了滑動(dòng)距離 我們就只剩拖動(dòng)按鈕這一步了,先看代碼

 # 省略上面的代碼 1.1 和1.2
 # 代碼1.3
 # 接著上面的 distance = y * (280 / 680) - 21 繼續(xù)
 # 模擬人為拖動(dòng)按鈕
 has_gone_dist = 0
 remaining_dist = distance
 # distance += randint(-10, 10)
 # 按下鼠標(biāo)左鍵
 ActionChains(browser).click_and_hold(element).perform()
 time.sleep(0.5)
 while remaining_dist > 0:
  ratio = remaining_dist / distance
  if ratio < 0.2:
  # 開始階段移動(dòng)較慢
  span = random.randint(5, 8)
  elif ratio > 0.8:
  # 結(jié)束階段移動(dòng)較慢
  span = random.randint(5, 8)
  else:
  # 中間部分移動(dòng)快
  span = random.randint(10, 16)
  ActionChains(browser).move_by_offset(span, random.randint(-5, 5)).perform()
  remaining_dist -= span
  has_gone_dist += span
  time.sleep(random.randint(5, 20) / 100)

 ActionChains(browser).move_by_offset(remaining_dist, random.randint(-5, 5)).perform()
 ActionChains(browser).release(on_element=element).perform()

到這里按鈕拖動(dòng)就已經(jīng)完成了,但圖片分析不是人在操作畢竟有誤差,所以我們需要判斷滑動(dòng)按鈕是否已經(jīng)成功,如果失敗了我們得讓程序繼續(xù)循環(huán)去刷新驗(yàn)證碼然后拖動(dòng)直到成功為止

 # 省略代碼 1.1, 1.2, 1.3 在1.3下繼續(xù)寫
 # 獲取當(dāng)前的網(wǎng)頁地址
 url2 = browser.current_url
 
 # frame切回到上一層
 browser.switch_to.parent_frame()
 
 # 判斷拖動(dòng)按鈕后網(wǎng)頁地址是否有改變,如果變了則說明登錄成功(失敗則停留在該頁面)
 if url1 == url2:
 try :
 print(browser.find_element_by_class_name('tcaptcha-title').text)
 print('滑動(dòng)失敗!')
 except : 
 print('帳號(hào)密碼有誤!')
 else :
 print('登錄成功!') 

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python反編譯的兩種實(shí)現(xiàn)方式

    Python反編譯的兩種實(shí)現(xiàn)方式

    這篇文章主要介紹了Python反編譯的兩種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • python讀取npy文件數(shù)據(jù)實(shí)例

    python讀取npy文件數(shù)據(jù)實(shí)例

    npy文件用于存儲(chǔ)重建ndarray所需的數(shù)據(jù)、圖形、dtype?和其他信息,下面這篇文章主要給大家介紹了關(guān)于python讀取npy文件數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • Python 恐龍跑跑小游戲?qū)崿F(xiàn)流程

    Python 恐龍跑跑小游戲?qū)崿F(xiàn)流程

    大家好,本篇文章主要講的是用python實(shí)現(xiàn)谷歌小恐龍小游戲,看看這是你斷網(wǎng)時(shí)的樣子么,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • 詳解Python和Rust中內(nèi)存管理機(jī)制的實(shí)現(xiàn)與對(duì)比

    詳解Python和Rust中內(nèi)存管理機(jī)制的實(shí)現(xiàn)與對(duì)比

    Python和Rust都采用了垃圾收集(Garbage?Collection)機(jī)制來管理內(nèi)存,但它們各自的實(shí)現(xiàn)方式有很大的不同,下面就跟隨小編一起來深入了解下二者的區(qū)別吧
    2024-03-03
  • python迭代器常見用法實(shí)例分析

    python迭代器常見用法實(shí)例分析

    這篇文章主要介紹了python迭代器常見用法,結(jié)合實(shí)例形式分析了Python迭代器概念、功能、常見操作方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • 詳解Python中鍵盤鼠標(biāo)的相關(guān)操作

    詳解Python中鍵盤鼠標(biāo)的相關(guān)操作

    pyautogui模塊,規(guī)范一點(diǎn)大寫就是PyAutoGUI模塊,是用來實(shí)現(xiàn)自動(dòng)化腳本的一個(gè)十分得力的小助手。他可以操控鍵盤和鼠標(biāo),可以寫許多工具。本文就來講講如何利用這個(gè)模塊實(shí)現(xiàn)鍵盤鼠標(biāo)的相關(guān)操作,需要的可以參考一下
    2023-01-01
  • python獲取本機(jī)外網(wǎng)ip的方法

    python獲取本機(jī)外網(wǎng)ip的方法

    這篇文章主要介紹了python獲取本機(jī)外網(wǎng)ip的方法,可實(shí)現(xiàn)從外網(wǎng)顯示IP的網(wǎng)站獲取本機(jī)IP的功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Python數(shù)據(jù)分析之?Matplotlib?3D圖詳情

    Python數(shù)據(jù)分析之?Matplotlib?3D圖詳情

    本文主要介紹了Python數(shù)據(jù)分析之Matplotlib 3D圖詳情,Matplotlib提供了mpl_toolkits.mplot3d工具包來進(jìn)行3D圖表的繪制,下文總結(jié)了更多相關(guān)資料,需要的小伙伴可以參考一下
    2022-05-05
  • Python getattr()函數(shù)使用方法代碼實(shí)例

    Python getattr()函數(shù)使用方法代碼實(shí)例

    這篇文章主要介紹了Python getattr()函數(shù)使用方法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Python基于回溯法子集樹模板解決數(shù)字組合問題實(shí)例

    Python基于回溯法子集樹模板解決數(shù)字組合問題實(shí)例

    這篇文章主要介紹了Python基于回溯法子集樹模板解決數(shù)字組合問題,簡(jiǎn)單描述了數(shù)字組合問題并結(jié)合實(shí)例形式分析了Python回溯法子集樹模板解決數(shù)字組合問題的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09

最新評(píng)論

温宿县| 潼南县| 山阴县| 府谷县| 常德市| 阿图什市| 梧州市| 宣武区| 乌拉特后旗| 盐津县| 五家渠市| 武穴市| 长寿区| 聂荣县| 治多县| 万山特区| 易门县| 沙坪坝区| 郸城县| 上犹县| 依安县| 嘉义县| 普宁市| 连江县| 峨边| 呈贡县| 上犹县| 呼和浩特市| 嘉兴市| 台东县| 邹平县| 北辰区| 若羌县| 清丰县| 道真| 临颍县| 高阳县| 盐亭县| 高平市| 吴川市| 宕昌县|