中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • python爬蟲中如何使用selenium+opencv識別滑動驗證并模擬登陸知乎功能

python爬蟲中如何使用selenium+opencv識別滑動驗證并模擬登陸知乎功能

發布時間:2021-09-13 18:43:10 來源:億速云 閱讀:292 作者:小新 欄目:開發技術

小編給大家分享一下python爬蟲中如何使用selenium+opencv識別滑動驗證并模擬登陸知乎功能,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

滑動驗證距離

分別獲取驗證碼背景圖和滑塊圖兩張照片,然后利用opencv庫,通過高斯模糊和Canny算法進行處理,然后通過matchTemplate方法進行兩張圖的匹配,獲得滑動距離。需要注意的是,知乎驗證碼在進行操作的時候,需要在原有基礎上再向右偏移10px距離

def get_distance(self, bg_img_path='./bg.png', slider_img_path='./slider.png'):
        """獲取滑塊移動距離"""

        # 背景圖片處理
        bg_img = cv.imread(bg_img_path, 0)  # 讀入灰度圖片
        bg_img = cv.GaussianBlur(bg_img, (3, 3), 0)  # 高斯模糊去噪
        bg_img = cv.Canny(bg_img, 50, 150)  # Canny算法進行邊緣檢測
        # 滑塊做同樣處理
        slider_img = cv.imread(slider_img_path, 0)
        slider_img = cv.GaussianBlur(slider_img, (3, 3), 0)
        slider_img = cv.Canny(slider_img, 50, 150)
        # 尋找最佳匹配
        res = cv.matchTemplate(bg_img, slider_img, cv.TM_CCOEFF_NORMED)
        # 最小值,最大值,并得到最小值, 最大值的索引
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
        # 例如:(-0.05772797390818596, 0.30968162417411804, (0, 0), (196, 1))
        top_left = max_loc[0]  # 橫坐標
        return top_left

滑塊運動軌跡

模擬人的行為,到缺口位置時,繼續向后滑動一段距離,然后再回退到準確位置

def get_tracks(self, distance):
        '''滑動軌跡 '''

        tracks = []
        v = 0
        t = 0.2  # 單位時間
        current = 0  # 滑塊當前位移
        distance += 10  # 多移動10px,然后回退
        while current < distance:
            if current < distance * 5 / 8:
                a = random.randint(1, 3)
            else:
                a = -random.randint(2, 4)
            v0 = v  # 初速度
            track = v0 * t + 0.5 * a * (t ** 2)  # 單位時間(0.2s)的滑動距離
            tracks.append(round(track))  # 加入軌跡
            current += round(track)
            v = v0 + a * t
        #回退到大致位置
        for i in range(5):
            tracks.append(-random.randint(1, 3))
        return tracks

鼠標滑動操作

通過selenium中的鼠標動作鏈,按照滑動軌跡進行滑動

def mouse_move(self,slide,tracks):
        '''鼠標滑動'''

        #鼠標點擊滑塊并按照不放
        ActionChains(self.driver).click_and_hold(slide).perform()
        #按照軌跡進行滑動,
        for track in tracks:
            ActionChains(self.driver).move_by_offset(track, 0).perform() 
        ActionChains(self.driver).release(slide).perform()

規避知乎selenium檢測

使用selenium自動化測試爬取知乎的時候出現了:錯誤代碼10001:請求異常請升級客戶端后重新嘗試,這個錯誤的產生是由于知乎可以檢測selenium自動化測試的腳本

使用chrome的遠程調試模式結合selenium來遙控操作chrome進行抓取,這樣就會規避selenium被網站檢測到

添加環境變量

將chrome.exe的目錄添加到系統環境變量,比如C:\Program Files\Google\Chrome\Application,這樣就可以直接在命令行輸入chrome.exe啟動瀏覽器

打開cmd窗口,執行命令

chrome.exe --remote-debugging-port=9222 --user-data-dir="E:\eliwang\selenium_data"

注意端口不要被占用,user-data-dir用來指明配置文件的路徑,自定義

此時會開啟瀏覽器,并打開一個新的標簽頁

selenium接管的主要代碼

options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

關閉瀏覽器窗口

1、使用瀏覽器對象的close()方法,quit()方法不行。

2、手動打開,手動關閉

完整登陸代碼

# coding:utf-8

import cv2 as cv
import time
import random
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as WAIT
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from urllib.request import urlretrieve


class Zhihu_login:
    '''知乎模擬登陸'''

    def __init__(self):
        options = webdriver.ChromeOptions()
        #操控chrome瀏覽器
        options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
        self.driver = webdriver.Chrome(options=options)
        self.wait = WAIT(self.driver, 5)
        self.url = 'https://www.zhihu.com/'
        self.bg_img_path = './bg.png'
        self.slider_img_path = './slider.png'


    def run(self):
        '''執行入口'''

        self.driver.get(self.url)
        try:
            if WAIT(self.driver,3).until(EC.presence_of_element_located((By.ID,'Popover15-toggle'))):
                print('登陸成功')
                self.save_cookie()
                self.driver.close()
        except:
            # 切換到密碼登陸
            self.wait.until(EC.element_to_be_clickable((By.XPATH, '//div[contains(@class,"SignFlow-tabs")]/div[2]'))).click()
            name_input = self.driver.find_element_by_name('username')
            name_input.clear()
            name_input.send_keys('賬號')
            pass_input = self.driver.find_element_by_name('password')
            pass_input.clear()
            pass_input.send_keys('密碼')
            self.wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@type="submit"]'))).click()  # 點擊登陸按鈕
            time.sleep(1)
            #進行滑動驗證,最多嘗試5次重新驗證
            if self.slide_verify():
                print('登陸成功')
                self.save_cookie()
                self.driver.close()
            else:
                print('第1次登陸失敗')
                for i in range(4):
                    print('正在嘗試第%d次登陸'%(i+2))
                    if self.slide_verify():
                        print('第%d次登陸成功'%(i+2))
                        self.save_cookie()
                        self.driver.close()
                        return
                    print('第%d次登陸失敗' % (i + 2))
                print('登陸失敗5次,停止登陸')
                self.driver.close()


    def slide_verify(self):
        '''滑動驗證'''

        slider_button = self.wait.until(EC.element_to_be_clickable((By.XPATH, '//div[@class="yidun_slider"]')))
        self.bg_img_url = self.wait.until(EC.presence_of_element_located((By.XPATH, '//img[@class="yidun_bg-img"]'))).get_attribute('src')  # 獲取驗證碼背景圖url
        self.slider_img_url = self.wait.until(EC.presence_of_element_located((By.XPATH, '//img[@class="yidun_jigsaw"]'))).get_attribute('src')  # 獲取驗證碼滑塊圖url
        urlretrieve(self.bg_img_url, self.bg_img_path)
        urlretrieve(self.slider_img_url, self.slider_img_path)
        distance = self.get_distance(self.bg_img_path, self.slider_img_path)
        distance += 10  # 實際移動距離需要向右偏移10px
        tracks = self.get_tracks(distance)
        self.mouse_move(slider_button,tracks)
        try:
            element = self.wait.until(EC.presence_of_element_located((By.ID,'Popover15-toggle')))
        except:
            return False
        else:
            return True

    def save_cookie(self):
        cookie = {}
        for item in self.driver.get_cookies():
            cookie[item['name']] = item['value']
        print(cookie)
        print('成功獲取登陸知乎后的cookie信息')


    def mouse_move(self,slide,tracks):
        '''鼠標滑動'''

        #鼠標點擊滑塊并按照不放
        ActionChains(self.driver).click_and_hold(slide).perform()
        #按照軌跡進行滑動,
        for track in tracks:
            ActionChains(self.driver).move_by_offset(track, 0).perform()
        ActionChains(self.driver).release(slide).perform()


    def get_distance(self, bg_img_path='./bg.png', slider_img_path='./slider.png'):
        """獲取滑塊移動距離"""

        # 背景圖片處理
        bg_img = cv.imread(bg_img_path, 0)  # 讀入灰度圖片
        bg_img = cv.GaussianBlur(bg_img, (3, 3), 0)  # 高斯模糊去噪
        bg_img = cv.Canny(bg_img, 50, 150)  # Canny算法進行邊緣檢測
        # 滑塊做同樣處理
        slider_img = cv.imread(slider_img_path, 0)
        slider_img = cv.GaussianBlur(slider_img, (3, 3), 0)
        slider_img = cv.Canny(slider_img, 50, 150)
        # 尋找最佳匹配
        res = cv.matchTemplate(bg_img, slider_img, cv.TM_CCOEFF_NORMED)
        # 最小值,最大值,并得到最小值, 最大值的索引
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
        # 例如:(-0.05772797390818596, 0.30968162417411804, (0, 0), (196, 1))
        top_left = max_loc[0]  # 橫坐標
        return top_left


    def get_tracks(self, distance):
        '''滑動軌跡 '''

        tracks = []
        v = 0
        t = 0.2  # 單位時間
        current = 0  # 滑塊當前位移
        distance += 10  # 多移動10px,然后回退
        while current < distance:
            if current < distance * 5 / 8:
                a = random.randint(1, 3)
            else:
                a = -random.randint(2, 4)
            v0 = v  # 初速度
            track = v0 * t + 0.5 * a * (t ** 2)  # 單位時間(0.2s)的滑動距離
            tracks.append(round(track))  # 加入軌跡
            current += round(track)
            v = v0 + a * t
        #回退到大致位置
        for i in range(5):
            tracks.append(-random.randint(1, 3))
        return tracks


if __name__ == '__main__':
    Zhihu_login().run()

看完了這篇文章,相信你對“python爬蟲中如何使用selenium+opencv識別滑動驗證并模擬登陸知乎功能”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

光泽县| 梁山县| 图木舒克市| 丹巴县| 额尔古纳市| 镇宁| 砚山县| 茶陵县| 榕江县| 象州县| 新安县| 通化市| 沁水县| 龙州县| 保德县| 阳西县| 奎屯市| 利辛县| 晴隆县| 石楼县| 九江县| 织金县| 玛曲县| 托克托县| 宜阳县| 万源市| 库尔勒市| 长岭县| 祥云县| 舟曲县| 油尖旺区| 星座| 融水| 紫阳县| 田林县| 天柱县| 隆昌县| 玉山县| 辽中县| 泸水县| 建平县|