驗證碼破解 | Selenium模擬登陸簡書

使用超級鷹打碼平臺處理登陸的文字點擊驗證碼web

import time
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from chaojiying import Chaojiying


#爲簡書的用戶帳號和密碼
EMAIL = 
PASSWORD = 

#此四者分別爲,超級鷹的用戶名,密碼,軟件ID,和驗證碼類型
CHAOJIYING_USERNAME = 
CHAOJIYING_PASSWORD = 
CHAOJIYING_SOFT_ID = 
CHAOJIYING_KIND =           


class Jianshu():
    def __init__(self):
        self.url = 'https://www.jianshu.com/sign_in'
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 20)
        self.email = EMAIL
        self.password = PASSWORD
        self.chaojiying = Chaojiying(CHAOJIYING_USERNAME,     CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID)

    def __del__(self):
        self.browser.close()

    def open(self):
        """
        打開網頁輸入用戶名密碼
        :return: None
        """
        self.browser.get(self.url)
        email = self.wait.until(EC.presence_of_element_located((By.ID, 'session_email_or_mobile_number')))
        password = self.wait.until(EC.presence_of_element_located((By.ID, 'session_password')))
        email.send_keys(self.email)
        password.send_keys(self.password)

    def get_touclick_button(self):
        """
        獲取初始驗證按鈕
        :return:
        """
        button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'sign-in-button')))
        return button

    def get_touclick_element(self):
        """
        獲取驗證圖片對象
        :return: 圖片對象
        """
        element = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_widget')))
        return element

    def get_position(self):
        """
        獲取驗證碼位置
        :return: 驗證碼位置元組
        """
        element = self.get_touclick_element()
        time.sleep(2)
        location = element.location
        size = element.size
        top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']
        top = int(top)
        bottom = int(bottom)
        left = int(left)
        right = int(right)
        return (top, bottom, left, right)

    def get_screenshot(self):
        """
        獲取網頁截圖
        :return: 截圖對象
        """
        screenshot = self.browser.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
        return screenshot

    def get_touclick_image(self, name='captch.png'):
        """
        獲取驗證碼圖片
        :return: 圖片對象
        """
        top, bottom, left, right = self.get_position()
        print('驗證碼位置', top, bottom, left, right)
        screenshot = self.get_screenshot()
        captcha = screenshot.crop((left, top, right, bottom))
        captcha.save(name)
        return captcha

    def get_points(self, captcha_result):
        """
        解析識別結果
        :param captcha_result: 識別結果
        :return: 轉化後的結果
        """
        groups = captcha_result.get('pic_str').split('|')
        locations = [[int(number) for number in group.split(',')] for group in groups]
        return locations

    def touch_click_words(self, locations):
        """
        點擊驗證圖片
        :param locations: 點擊位置
        :return: None
        """
        for location in locations:
            print(location)
            ActionChains(self.browser).move_to_element_with_offset(self.get_touclick_element(), location[0],location[1]).click().perform()
            time.sleep(1)

    def touch_click_verify(self):
        """
        點擊驗證按鈕
        :return: None
        """
        button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_commit')))
        button.click()

    def login(self):
        """
        登陸
        :return: None
        """
        submit = self.wait.until(EC.element_to_be_clickable((By.ID, '_submit')))
        submit.click()
        time.sleep(10)
        print('登陸成功')

    def crack(self):
        """
        破解入口
        :return: None
        """
        self.open()

        # 點擊驗證按鈕
        button = self.get_touclick_button()
        button.click()

        # 獲取驗證碼圖片
        image = self.get_touclick_image()
        bytes_array = BytesIO()
        image.save(bytes_array, format='PNG')

        # 識別驗證碼
        result = self.chaojiying.post_pic(bytes_array.getvalue(), CHAOJIYING_KIND)
        print(result)
        locations = self.get_points(result)
        self.touch_click_words(locations)
        self.touch_click_verify()

        # 斷定是否成功
        # time.sleep(10)
        try:
            success = self.wait.until(
                EC.text_to_be_present_in_element((By.CLASS_NAME, 'btn write-btn'), '驗證成功'))
            print(success)
        except:
            # 失敗後重試
            # if not success:
            print("驗證失敗,從新嘗試")
            self.crack()
            # else:
            #     self.login()


if __name__ == '__main__':
    crack = Jianshu()
    crack.crack()

輸出結果:session

驗證碼位置 256 664 354 672
{'err_no': 0, 'err_str': 'OK', 'pic_id': '2084311523163100007', 'pic_str': '216,256|91,189|142,243', 'md5': 'c25ad4f3e9746e9aa6fe4930ed10db4a'}
[216, 256]
[91, 189]
[142, 243]post

 

相關文章
相關標籤/搜索