1,cookie登錄
- 利用cookie的特性:cookie會保持較長的時間,來避免用戶頻繁登錄
- cookie一般由前端開發用js生成,可以利用抓包嘗試下破解,不過這個難度有點高,不過破解js本就是爬蟲必須直面面對的
- 2OCR庫里的tesseract(光學文字識別)可以解決大多數的傳統驗證碼
- 軟件tesserract-ocr先安裝,然后安裝pytesserract類庫
注意:
- Windows需要下載軟件安裝包,再配置環境變量
- linux 直接在命令窗口輸入:sudo apt-get tesseract-ocr 模擬瀏覽器,selenium和PIL庫的截屏功能,來識別驗證碼(save_screenshot截圖)
打碼平台
- 打碼兔和QQ超人打碼,有提供Python的接入方式,人工打碼平台需要收費。
- 以QQ超人打碼平台,先要注冊開發者賬號,在識別程序中需要填寫個人賬號進行認證計費,登錄之后接入,開始計費(一個碼六分錢)
selenium 來模擬拉動來破解滑動驗證碼
由於時間過久,滑動驗證碼已經更改,滑動驗證碼已經被放棄,現僅供參考使用
交流群:1029344413 分享資料、源碼
from PIL import Image from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.desired_capabilities import DesiredCapabilities import random headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" } chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option('w3c', False) caps = DesiredCapabilities.CHROME caps['loggingPrefs'] = {'performance': 'ALL'} class SliderVerificationCode(object): def __init__(self): # 初始化一些信息 self.left = 60 # 定義一個左邊的起點 缺口一般離圖片左側有一定的距離 有一個滑塊 self.url = 'https://passport.bilibili.com/login' self.driver = webdriver.Chrome(executable_path='C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe') self.wait = WebDriverWait(self.driver, 20) # 設置等待時間20秒 self.phone = "17369251763" self.passwd = "abcdefg" def input_name_password(self): # 輸入賬號密碼 self.driver.get(self.url) self.driver.maximize_window() input_name = self.driver.find_element_by_xpath("//input[@id='login-username']") input_pwd = self.driver.find_element_by_xpath("//input[@id='login-passwd']") input_name.send_keys("username") self.wait = WebDriverWait(self.driver, 3) input_pwd.send_keys("passport") def click_login_button(self): # 點擊登錄按鈕,出現驗證碼圖片 login_btn = self.driver.find_element_by_class_name("btn-login") sleep(random.randint(3, 6)) login_btn.click() def get_geetest_image(self): # 獲取驗證碼圖片 gapimg = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_bg'))) sleep(2) gapimg.screenshot(r'./captcha1.png') # 通過js代碼修改標簽樣式 顯示圖片2 js = 'var change = document.getElementsByClassName("geetest_canvas_fullbg");change[0].style = "display:block;"' self.driver.execute_script(js) sleep(2) fullimg = self.wait.until( EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_slice'))) fullimg.screenshot(r'./captcha2.png') def is_similar(self, image1, image2, x, y): '''判斷兩張圖片 各個位置的像素是否相同 #image1:帶缺口的圖片 :param image2: 不帶缺口的圖片 :param x: 位置x :param y: 位置y :return: (x,y)位置的像素是否相同 ''' # 獲取兩張圖片指定位置的像素點 pixel1 = image1.load()[x, y] pixel2 = image2.load()[x, y] # 設置一個閾值 允許有誤差 threshold = 60 # 彩色圖 每個位置的像素點有三個通道 if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs( pixel1[2] - pixel2[2]) < threshold: return True else: return False def get_diff_location(self): # 獲取缺口圖起點 captcha1 = Image.open('captcha1.png') captcha2 = Image.open('captcha2.png') for x in range(self.left, captcha1.size[0]): # 從左到右 x方向 for y in range(captcha1.size[1]): # 從上到下 y方向 if not self.is_similar(captcha1, captcha2, x, y): return x # 找到缺口的左側邊界 在x方向上的位置 def get_move_track(self, gap): track = [] # 移動軌跡 current = 0 # 當前位移 # 減速閾值 mid = gap * 4 / 5 # 前4/5段加速 后1/5段減速 t = 0.2 # 計算間隔 v = 0 # 初速度 while current < gap: if current < mid: a = 5 # 加速度為+5 else: a = -5 # 加速度為-5 v0 = v # 初速度v0 v = v0 + a * t # 當前速度 move = v0 * t + 1 / 2 * a * t * t # 移動距離 current += move # 當前位移 track.append(round(move)) # 加入軌跡 return track def move_slider(self, track): slider = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.geetest_slider_button'))) ActionChains(self.driver).click_and_hold(slider).perform() for x in track: # 只有水平方向有運動 按軌跡移動 ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform() sleep(1) ActionChains(self.driver).release().perform() # 松開鼠標 def main(self): self.input_name_password() self.click_login_button() self.get_geetest_image() gap = self.get_diff_location() # 缺口左起點位置 gap = gap - 6 # 減去滑塊左側距離圖片左側在x方向上的距離 即為滑塊實際要移動的距離 track = self.get_move_track(gap) self.move_slider(track) if __name__ == "__main__": springAutumn = SliderVerificationCode() springAutumn.main()
