欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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)解鎖),先簡單記錄一下。

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

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

其實(shí)登錄賬號(hào)的部分本來很簡單,用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ū)別

先看本地處理過后的圖片

很明顯能夠看到長是680

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

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

按鈕需要滑動(dòng)的距離(網(wǎng)頁) = 拼圖的還原距離(本地圖片) * (網(wǎ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('登錄成功!') 

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

相關(guān)文章

  • python鼠標(biāo)繪圖附代碼

    python鼠標(biāo)繪圖附代碼

    這篇文章主要為大家介紹了python鼠標(biāo)繪圖的實(shí)現(xiàn)完整示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Python pathlib模塊實(shí)例詳解

    Python pathlib模塊實(shí)例詳解

    本文給大家介紹了Python的pathlib 模塊,為 Python 工程師對(duì)該模塊的使用提供了支撐,讓大家了解如何使用 pathlib 模塊讀寫文件、操縱文件路徑和基礎(chǔ)文件系統(tǒng),統(tǒng)計(jì)目錄下的文件類型以及查找匹配目錄下某一類型文件等,需要的朋友參考下吧
    2023-05-05
  • Python自動(dòng)化測(cè)試之登錄腳本的實(shí)現(xiàn)

    Python自動(dòng)化測(cè)試之登錄腳本的實(shí)現(xiàn)

    本文主要介紹了Python自動(dòng)化測(cè)試之登錄腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python數(shù)據(jù)模型與Python對(duì)象模型的相關(guān)總結(jié)

    Python數(shù)據(jù)模型與Python對(duì)象模型的相關(guān)總結(jié)

    這篇文章主要介紹了Python數(shù)據(jù)模型與Python對(duì)象模型的相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2021-01-01
  • python實(shí)現(xiàn)備份目錄的方法

    python實(shí)現(xiàn)備份目錄的方法

    這篇文章主要介紹了python實(shí)現(xiàn)備份目錄的方法,實(shí)例總結(jié)了Python實(shí)現(xiàn)備份目錄的三種常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • django views重定向到帶參數(shù)的url

    django views重定向到帶參數(shù)的url

    這篇文章主要介紹了django views重定向到帶參數(shù)的url,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Python常用內(nèi)置函數(shù)總結(jié)

    Python常用內(nèi)置函數(shù)總結(jié)

    這篇文章主要介紹了Python常用內(nèi)置函數(shù)總結(jié),本文羅列了數(shù)學(xué)相關(guān) 、功能相關(guān)、類型轉(zhuǎn)換、字符串處理、序列處理函數(shù)等常用內(nèi)置函數(shù),需要的朋友可以參考下
    2015-02-02
  • Python中實(shí)現(xiàn)變量賦值傳遞時(shí)的引用和拷貝方法

    Python中實(shí)現(xiàn)變量賦值傳遞時(shí)的引用和拷貝方法

    下面小編就為大家分享一篇Python中實(shí)現(xiàn)變量賦值傳遞時(shí)的引用和拷貝方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • pandas的唯一值、值計(jì)數(shù)以及成員資格的示例

    pandas的唯一值、值計(jì)數(shù)以及成員資格的示例

    今天小編就為大家分享一篇pandas的唯一值、值計(jì)數(shù)以及成員資格的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • python進(jìn)度條庫tqdm的基本操作方法

    python進(jìn)度條庫tqdm的基本操作方法

    這篇文章主要介紹了python進(jìn)度條庫tqdm的基本操作方法,tqdm實(shí)時(shí)輸出處理進(jìn)度而且占用的CPU資源非常少,支持windows、Linux、mac等系統(tǒng),支持循環(huán)處理、多進(jìn)程、遞歸處理、還可以結(jié)合linux的命令來查看處理情況等優(yōu)點(diǎn),下面對(duì)其更多內(nèi)容詳細(xì)介紹,需要的朋友可以參考一下
    2022-03-03

最新評(píng)論