日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】

發(fā)布時間:2023/12/10 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python3 爬蟲學(xué)習(xí)筆記第十四章 —— 【驗證碼對抗系列 — 點(diǎn)觸驗證碼】

文章目錄

  • 【14.1】關(guān)于點(diǎn)觸驗證碼
  • 【14.2】點(diǎn)觸驗證碼攻克思路
  • 【14.3】模擬登錄 12306 — 總體思路
  • 【14.4】主函數(shù)
  • 【14.5】初始化函數(shù)
  • 【14.6】破解入口函數(shù)
  • 【14.7】賬號密碼輸入函數(shù)
  • 【14.8】頁面截圖函數(shù)
  • 【14.9】驗證碼元素查找函數(shù)
  • 【14.10】獲取驗證碼坐標(biāo)函數(shù)
  • 【14.11】驗證碼剪裁函數(shù)
  • 【14.12】驗證碼坐標(biāo)解析函數(shù)
  • 【14.13】驗證碼模擬點(diǎn)擊函數(shù)
  • 【14.14】模擬點(diǎn)擊登陸函數(shù)
  • 【14.15】效果實(shí)現(xiàn)動圖
  • 【14.16】完整代碼


【14.1】關(guān)于點(diǎn)觸驗證碼

點(diǎn)觸驗證碼是由杭州微觸科技有限公司研發(fā)的新一代的互聯(lián)網(wǎng)驗證碼,使用點(diǎn)擊的形式完成驗證,采用專利的印刷算法以及加密算法,保證每次請求到的驗證圖具有極高的安全性,常見的點(diǎn)觸驗證碼如下:


【14.2】點(diǎn)觸驗證碼攻克思路

點(diǎn)觸驗證碼相對其他類型驗證碼比較復(fù)雜,如果依靠 OCR 圖像識別點(diǎn)觸驗證碼,則識別難度非常大,此時就要用到互聯(lián)網(wǎng)的驗證碼服務(wù)平臺,這些服務(wù)平臺全部都是人工在線識別,準(zhǔn)確率非常高,原理就是先將驗證碼圖片提交給平臺,平臺會返回識別結(jié)果在圖片中的坐標(biāo)位置,然后我們再解析坐標(biāo)模擬點(diǎn)擊即可,常見的打碼平臺有超級鷹、云打碼等,打碼平臺是收費(fèi)的,拿超級鷹來說,1元 = 1000題分,識別一次驗證碼將花費(fèi)一定的題分,不同類型驗證碼需要的題分不同,驗證碼越復(fù)雜所需題分越高,比如 7 位中文漢字需要 70 題分,常見 4 ~ 6 位英文數(shù)字只要 10 題分,其他打碼平臺價格也都差不多

以下以超級鷹打碼平臺和中國鐵路12306官網(wǎng)來做練習(xí)


【14.3】模擬登錄 12306 — 總體思路

首先在超級鷹打碼平臺注冊賬號并申請一個軟件 ID,官網(wǎng):http://www.chaojiying.com/ ,先充值一塊錢得到 1000 題分,觀察 12306 官網(wǎng),發(fā)現(xiàn)驗證碼是要我們點(diǎn)擊所有滿足條件的圖片,一般有 1~4 張圖片滿足要求,由此可確定在超級鷹打碼平臺的驗證碼類型為 9004(坐標(biāo)多選,返回1~4個坐標(biāo),如:x1,y1|x2,y2|x3,y3), 獲取其 Python API:http://www.chaojiying.com/download/Chaojiying_Python.rar ,然后用 Selenium 模擬登陸,獲取到驗證碼,并將驗證碼發(fā)送給超級鷹后臺,返回識別圖片的坐標(biāo),最后模擬點(diǎn)擊即可,整個過程的實(shí)現(xiàn)由主程序 12306.py 和超級鷹 API chaojiying.py 組成

整個程序包含的函數(shù):

def __init__(): 初始化 WebDriver、Chaojiying 對象等 def crack(): 破解入口、獲取、識別驗證碼、模擬登錄 def open(): 賬號密碼輸入 def get_screenshot(): 整個頁面截圖 def get_touclick_element(): 獲取驗證碼位置 def get_position(): 獲取驗證碼坐標(biāo) def get_touclick_image(): 剪裁驗證碼部分 def get_points(self, captcha_result): 分析超級鷹返回的坐標(biāo) def touch_click_words(self, locations): 模擬點(diǎn)擊符合要求的圖片 def login(self): 點(diǎn)擊登陸按鈕,完成模擬登錄

整個程序用到的庫:

import time from io import BytesIO from PIL import Image from selenium import webdriver from selenium.webdriver.chrome.options import Options 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 from selenium.common.exceptions import TimeoutException

【14.4】主函數(shù)

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

【14.5】初始化函數(shù)

USERNAME = '155********' PASSWORD = '***********'CHAOJIYING_USERNAME = '*******' CHAOJIYING_PASSWORD = '*******' CHAOJIYING_SOFT_ID = '********' CHAOJIYING_KIND = '9004'class CrackTouClick():def __init__(self):self.url = 'https://kyfw.12306.cn/otn/resources/login.html'path = r'F:\PycharmProjects\Python3爬蟲\chromedriver.exe'chrome_options = Options()chrome_options.add_argument('--start-maximized')self.browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)self.wait = WebDriverWait(self.browser, 20)self.email = USERNAMEself.password = PASSWORDself.chaojiying = Chaojiying_Client(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID)

定義 12306 賬號(USERNAME)、密碼(PASSWORD)、超級鷹用戶名(CHAOJIYING_USERNAME)、超級鷹登錄密碼(CHAOJIYING_PASSWORD)、超級鷹軟件 ID(CHAOJIYING_SOFT_ID)、驗證碼類型(CHAOJIYING_KIND),登錄鏈接 url:https://kyfw.12306.cn/otn/resources/login.html ,谷歌瀏覽器驅(qū)動的目錄(path),瀏覽器啟動參數(shù),并將相關(guān)參數(shù)傳遞給超級鷹 API


【14.6】破解入口函數(shù)

def crack(self):self.open()image = self.get_touclick_image()bytes_array = BytesIO()image.save(bytes_array, format='PNG')result = self.chaojiying.PostPic(bytes_array.getvalue(), CHAOJIYING_KIND)print(result)locations = self.get_points(result)self.touch_click_words(locations)self.login()try:success = self.wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.welcome-name'), '用戶姓名'))print(success)cc = self.browser.find_element(By.CSS_SELECTOR, '.welcome-name')print(cc.text)except TimeoutException:self.chaojiying.ReportError(result['pic_id'])self.crack()

調(diào)用 open() 函數(shù)輸入賬號密碼

調(diào)用 get_touclick_image() 函數(shù)獲取驗證碼圖片

利用超級鷹 Python API PostPic() 方法即可把圖片發(fā)送給超級鷹后臺,發(fā)送的圖像是字節(jié)流格式,返回的結(jié)果是一個 JSON,如果識別成功,典型的返回結(jié)果類似于:{'err_no': 0, 'err_str': 'OK', 'pic_id': '6002001380949200001', 'pic_str': '132,127|56,77', 'md5': '1f8e1d4bef8b11484cb1f1f34299865b'},其中,pic_str 就是識別的文字的坐標(biāo),是以字符串形式返回的,每個坐標(biāo)都以 | 分隔

調(diào)用 get_points() 函數(shù)解析超級鷹識別結(jié)果

調(diào)用 touch_click_words() 函數(shù)對符合要求的圖片進(jìn)行點(diǎn)擊,然后點(diǎn)擊登陸按鈕模擬登陸

使用 try-except 語句判斷是否出現(xiàn)了用戶信息,判斷依據(jù)是是否有用戶姓名的出現(xiàn),出現(xiàn)的姓名和實(shí)際姓名一致則登錄成功,如果失敗了就重試,超級鷹會返回該分值


【14.7】賬號密碼輸入函數(shù)

def open(self):self.browser.get(self.url)login = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-hd-account')))login.click()time.sleep(3)username = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-userName')))password = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-password')))username.send_keys(self.email)password.send_keys(self.password)

分析頁面可知,登陸頁面 URL 為:https://kyfw.12306.cn/otn/resources/login.html ,該頁面默認(rèn)出現(xiàn)的是掃描二維碼登陸,所以要先點(diǎn)擊賬號登錄,找到該 CSS 元素為 login-hd-account,調(diào)用 click() 方法實(shí)現(xiàn)模擬點(diǎn)擊,此時出現(xiàn)賬號密碼輸入框,同樣找到其 ID 分別為 J-userName 和 J-password,調(diào)用 send_keys() 方法輸入賬號密碼


【14.8】頁面截圖函數(shù)

def get_screenshot(self):screenshot = self.browser.get_screenshot_as_png()screenshot = Image.open(BytesIO(screenshot))return screenshot

對整個頁面進(jìn)行截圖


【14.9】驗證碼元素查找函數(shù)

def get_touclick_element(self):element = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-pwd-code')))return element

同樣分析頁面,驗證碼所在位置的 CSS 為 login-pwd-code


【14.10】獲取驗證碼坐標(biāo)函數(shù)

def get_position(self):element = self.get_touclick_element()time.sleep(3)location = element.locationsize = element.sizetop, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']return (top, bottom, left, right)

location 屬性可以返回該圖片對象在瀏覽器中的位置,坐標(biāo)軸是以屏幕左上角為原點(diǎn),x 軸向右遞增,y 軸向下遞增,size 屬性可以返回該圖片對象的高度和寬度,由此可以得到驗證碼的位置信息


【14.11】驗證碼剪裁函數(shù)

def get_touclick_image(self, name='12306.png'):top, bottom, left, right = self.get_position()screenshot = self.get_screenshot()captcha = screenshot.crop((left, top, right, bottom))captcha.save(name)return captcha

根據(jù)驗證碼的坐標(biāo)信息,對頁面截圖進(jìn)行剪裁,得到驗證碼部分,將其保存為 12306.png


【14.12】驗證碼坐標(biāo)解析函數(shù)

def get_points(self, captcha_result):groups = captcha_result.get('pic_str').split('|')locations = [[int(number) for number in group.split(',')] for group in groups]return locations

get_points() 方法將超級鷹的驗證碼識別結(jié)果變成列表的形式


【14.13】驗證碼模擬點(diǎn)擊函數(shù)

def touch_click_words(self, locations):for location in locations:print(location)ActionChains(self.browser).move_to_element_with_offset(self.get_touclick_element(), location[0]/1.25, location[1]/1.25).click().perform()

touch_click_words() 方法通過調(diào)用 move_to_element_with_offset() 方法依次傳入解析后的坐標(biāo),點(diǎn)擊即可


【14.14】模擬點(diǎn)擊登陸函數(shù)

def login(self):submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'J-login')))submit.click()

分析頁面,找到登陸按鈕的 ID 為 J-login,調(diào)用 click() 方法模擬點(diǎn)擊按鈕實(shí)現(xiàn)登錄


【14.15】效果實(shí)現(xiàn)動圖

最終實(shí)現(xiàn)效果圖:(關(guān)鍵信息已經(jīng)過打碼處理)


【14.16】完整代碼

12306.py

import time from io import BytesIO from PIL import Image from selenium import webdriver from selenium.webdriver.chrome.options import Options 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_Client from selenium.common.exceptions import TimeoutExceptionUSERNAME = '155********' PASSWORD = '***********'CHAOJIYING_USERNAME = '***********' CHAOJIYING_PASSWORD = '***********' CHAOJIYING_SOFT_ID = '******' CHAOJIYING_KIND = '9004'class CrackTouClick():def __init__(self): #登陸self.url = 'https://kyfw.12306.cn/otn/resources/login.html'path = r'F:\PycharmProjects\Python3爬蟲\chromedriver.exe'chrome_options = Options()chrome_options.add_argument('--start-maximized')self.browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)self.wait = WebDriverWait(self.browser, 20)self.email = USERNAMEself.password = PASSWORDself.chaojiying = Chaojiying_Client(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID)def crack(self):self.open()image = self.get_touclick_image()bytes_array = BytesIO()image.save(bytes_array, format='PNG')result = self.chaojiying.PostPic(bytes_array.getvalue(), CHAOJIYING_KIND)print(result)locations = self.get_points(result)self.touch_click_words(locations)self.login()try:success = self.wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR, '.welcome-name'), '譚仁侯'))print(success)cc = self.browser.find_element(By.CSS_SELECTOR, '.welcome-name')print(cc.text)except TimeoutException:self.chaojiying.ReportError(result['pic_id'])self.crack()def open(self):self.browser.get(self.url)login = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-hd-account')))login.click()time.sleep(3)username = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-userName')))password = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input#J-password')))username.send_keys(self.email)password.send_keys(self.password)def get_screenshot(self):screenshot = self.browser.get_screenshot_as_png()screenshot = Image.open(BytesIO(screenshot))return screenshotdef get_touclick_element(self):element = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login-pwd-code')))return elementdef get_position(self):element = self.get_touclick_element()time.sleep(3)location = element.locationsize = element.sizetop, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']return (top, bottom, left, right)def get_touclick_image(self, name='12306.png'):top, bottom, left, right = self.get_position()screenshot = self.get_screenshot()captcha = screenshot.crop((left, top, right, bottom))captcha.save(name)return captchadef get_points(self, captcha_result):groups = captcha_result.get('pic_str').split('|')locations = [[int(number) for number in group.split(',')] for group in groups]return locationsdef touch_click_words(self, locations):for location in locations:print(location)ActionChains(self.browser).move_to_element_with_offset(self.get_touclick_element(), location[0]/1.25, location[1]/1.25).click().perform()def login(self):submit = self.wait.until(EC.element_to_be_clickable((By.ID, 'J-login')))submit.click()if __name__ == '__main__':crack = CrackTouClick()crack.crack()

chaojiying.py

import requests from hashlib import md5class Chaojiying_Client(object):def __init__(self, username, password, soft_id):self.username = usernamepassword = password.encode('utf8')self.password = md5(password).hexdigest()self.soft_id = soft_idself.base_params = {'user': self.username,'pass2': self.password,'softid': self.soft_id,}self.headers = {'Connection': 'Keep-Alive','User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',}def PostPic(self, im, codetype):"""im: 圖片字節(jié)codetype: 題目類型 參考 http://www.chaojiying.com/price.html"""params = {'codetype': codetype,}params.update(self.base_params)files = {'userfile': ('ccc.jpg', im)}r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)return r.json()def ReportError(self, im_id):"""im_id:報錯題目的圖片ID"""params = {'id': im_id,}params.update(self.base_params)r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)return r.json() 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。