Selenium模拟登陸百度(帶驗證碼)

發布時間:2018-08-21 16:49:52編輯:Run閱讀(4455)

    利用Selenium模拟登陸解決驗證碼的問題

    驗證碼解決方案有很多種:

    1  通過第三方的打碼平台,識别率高...一般都是收費的,價格還不便宜

    2  自己通過切圖,再結合圖片識别的庫,去識别驗證碼... 簡單的驗證碼識别率還可以,但是複雜的驗證碼需要訓練(機器學習),     難度大

    3  通過手動登陸,獲取cookie信息,利用cookie實現免登陸... cookie一般都是有 有效期的,時間一過,那麼下次就又需要手       動登陸去獲取新的cookie,很繁瑣,實現簡單

    4  利用切圖把驗證碼圖片切出來,再通過手動輸入驗證碼去登陸(賬号,密碼可讓程序自行輸入)...每次登陸都需要手動輸入       驗證碼登陸,很繁瑣,實現簡單


    本次環境,将使用第四種方法來解決驗證碼問題

    目标網站:https://www.baidu.com   模拟登陸百度

    在模拟登陸百度之前,首先手動輸錯幾次,讓驗證碼顯示出來

    默認登陸是不需要驗證碼的,但輸錯2次之後,就需要驗證碼了,如下圖:

    blob.png


    PS:運行次腳本前,先模拟登陸失敗幾次,不然驗證碼不會出來


    Selenium登陸百度代碼如下:

    class LoginBaiDu(object):
        def __init__(self, url, password, username):
            self.url = url
            self.password = password
            self.username = username
            self.browser = self.getbrowser()
            self.run(self.browser)
    
        def getbrowser(self):
            chrome_options = webdriver.ChromeOptions()
            browser = webdriver.Chrome(options=chrome_options,
                                       executable_path=r'D:\chromedriver_2.41\chromedriver.exe')
            browser.get(self.url)
            # 清除cookies記錄
            browser.delete_all_cookies()
            return browser
    
        def run(self, browser):
            # 找到登陸按鈕
            browser.find_element_by_xpath("//div[@id='u1']/a[text()='登錄']").click()
            # 等待網站加載
            browser.implicitly_wait(3)
            # 定位彈出框
            browser.current_window_handle
            # 找到用戶名登錄按鈕,并點擊登錄
            browser.find_element_by_id('TANGRAM__PSP_10__footerULoginBtn').click()
            time.sleep(2)
            # 找到輸入用戶名的input标簽,模拟輸入用戶名
            browser.find_element_by_id("TANGRAM__PSP_10__userName").send_keys(self.username)
            time.sleep(3)
            # 找到輸入密碼的input标簽,模拟輸入密碼
            browser.find_element_by_id("TANGRAM__PSP_10__password").send_keys(self.password)
            time.sleep(10)
            # 對整個頁面進行截圖
            browser.get_screenshot_as_file('login.png')
            # 定位驗證碼的坐标
            code = browser.find_element_by_xpath("//span[@class='pass-verifyCodeImgParent']\
            /img[@id='TANGRAM__PSP_10__verifyCodeImg']")
            # 計算驗證碼四個點的坐标
            left = code.location['x']
            top = code.location['y']
            right = code.location['x'] + code.size['width']
            bottom = code.location['y'] + code.size['height']
            print("驗證碼坐标::", left, top, right, bottom)
            # 利用python的圖像處理庫,将驗證碼切出來,保存驗證碼code.png到當前目錄
            im = Image.open('login.png')
            im = im.crop((left, top, right, bottom))
            im.save('code.png')
            self.user_input(browser)
    
        def user_input(self, browser):
            # 查看code.png圖片,手動輸入驗證碼
            user_code = input("驗證碼:").strip()
            # 找到驗證碼的輸入框,并将手動輸入的驗證碼賦值到驗證碼輸入框
            browser.find_element_by_id("TANGRAM__PSP_10__verifyCode").send_keys(user_code)
            # 找到登陸按鈕,并點擊登錄
            browser.find_element_by_id("TANGRAM__PSP_10__submit").click()
            try:
                # 如果登陸成功,獲取用戶信息
                username = browser.find_element_by_id("s_username_top").text
                if username:
                    print('登陸成功')
                    print(username)
                # 登陸失敗,打印錯誤信息
            except Exception as e:
                print("登陸失敗錯誤信息:{}".format(e))
            finally:
                # 退出程序
                time.sleep(10)
                browser.quit()
    
    
    if __name__ == '__main__':
        url = 'https://www.baidu.com'
        username = '賬号'
        password = '密碼'
        st = LoginBaiDu(username=username, password=password, url=url)


    運行程序截圖

    程序到了驗證碼那裡,會停住,需要手動輸入驗證碼

    blob.png


    輸入驗證碼後,會自動賦值到驗證碼的輸入框

    blob.png


    然後就可以看到顯示登錄成功,打印用戶信息

    blob.png


    還會在當前目錄下,生成兩個png圖片

    login.png截圖

    blob.png


    code.png為切出來的驗證碼

    blob.png

關鍵字