1. 程式人生 > 實用技巧 >Selenium 模組3經典案例_規避檢測_js寫入破解伺服器Selenium識別 模擬登陸12306登陸

Selenium 模組3經典案例_規避檢測_js寫入破解伺服器Selenium識別 模擬登陸12306登陸

實戰專案,乾貨滿滿

import requests
from hashlib import md5
#實現規避檢測
from selenium.webdriver import FirefoxOptions
from selenium.webdriver import ChromeOptions
#規避檢測,'excludeSwitches', ['enable-automation']開發者模式
option = ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
#超級鷹打碼平臺
class Chaojiying_Client(object):
    def __init__(self, username, password, soft_id):
        self.username = username
        password =  password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.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: 圖片位元組
        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()

#使用selenium開啟登入頁面
from selenium import webdriver
import time
from PIL import Image
from selenium.webdriver import ActionChains
from selenium.webdriver.support import expected_conditions as EC, wait

#建立物件
#executable_path=path:下載好的驅動程式的路徑
bro = webdriver.Chrome(executable_path='chromedriver.exe',options=option)


#12306的登入網址
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
bro.execute_script('Object.defineProperties(navigator, {webdriver:{get:()=>undefined}})')
#視窗最大化
bro.maximize_window()
#點選賬號登入
bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
time.sleep(1)
while True:
    try:
        #save_screenshot就是將當前頁面進行截圖且儲存
        bro.save_screenshot('aa.png')
        #確定驗證碼圖片對應的左上角和右下角的座標(裁剪的區域就確定)
        code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
        location = code_img_ele.location  # 驗證碼圖片左上角的座標 x,y
        #print('location:',location)
        size = code_img_ele.size  #驗證碼標籤對應的長和寬
        #print('size:',size)
        #左上角和右下角座標
        rangle = (
        int(location['x']), int(location['y']), int(location['x'] + size['width']), int(location['y'] + size['height']))
        #至此驗證碼圖片區域就確定下來了
        i = Image.open('./aa.png')
        code_img_name = './code.png'
        #crop根據指定區域進行圖片裁剪
        frame = i.crop(rangle)
        frame.save(code_img_name)
        #將驗證碼圖片提交給超級鷹進行識別
        chaojiying = Chaojiying_Client('超級鷹帳號', '超級鷹密碼', '超級鷹軟體iD')	#使用者賬號>>密碼>>軟體ID
        im = open('code.png', 'rb').read()									#本地圖片檔案路徑 來替換 a.jpg 有時WIN系統須要//
        id=chaojiying.PostPic(im, 9004)['pic_id']                           #擷取的驗證碼照片以及驗證碼的類別代號
        result = chaojiying.PostPic(im, 9004)['pic_str']                    #識別結果
        all_list = [] #要儲存即將被點選的點的座標  [[x1,y1],[x2,y2]]
        #識別錯誤後,返回題分
        chaojiying.ReportError(id)
        if '|' in result:
            list_1 = result.split('|')
            print(list_1)
            count_1 = len(list_1)
            for i in range(count_1):
                xy_list = []
                x = int(list_1[i].split(',')[0])
                y = int(list_1[i].split(',')[1])
                xy_list.append(x)
                xy_list.append(y)
                all_list.append(xy_list)
        else:
            x = int(result.split(',')[0])
            y = int(result.split(',')[1])
            xy_list = []
            xy_list.append(x)
            xy_list.append(y)
            all_list.append(xy_list)
        #遍歷列表,使用動作鏈對每一個列表元素對應的x,y指定的位置進行點選操作
        for l in all_list:
            x = l[0]
            y = l[1]
            ActionChains(bro).move_to_element_with_offset(code_img_ele, x, y).click().perform()
            time.sleep(0.5)
        #輸入賬號和密碼
        put1=bro.find_element_by_id('J-userName')
        #當驗證碼識別錯誤後,需要清空賬號重新輸入
        put1.clear()
        put1.send_keys('帳號')  #你的賬號
        time.sleep(1)
        put2=bro.find_element_by_id('J-password')
        put2.clear()
        put2.send_keys('密碼') #你的密碼
        time.sleep(1)
        bro.find_element_by_id('J-login').click()
        #處理提示框
        time.sleep(3)
        span=bro.find_element_by_xpath('//*[@id="nc_1_n1z"]')
        action = ActionChains(bro)
        #點選長按指定的標籤
        action.click_and_hold(span).perform()
        action.drag_and_drop_by_offset(span,400,0).perform()
        time.sleep(8)
        while True:
            try:
                info=bro.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span').text
                print(info)
                if info=='哎呀,出錯了,點選重新整理再來一次':
                    bro.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span/a').click()
                    time.sleep(0.2)
                    span = bro.find_element_by_xpath('//*[@id="nc_1_n1z"]')
                    action = ActionChains(bro)
                    # 點選長按指定的標籤
                    action.click_and_hold(span).perform()
                    action.drag_and_drop_by_offset(span, 400, 0).perform()
                    time.sleep(7)
            except:
                print('ok!')
                break
        #釋放動作鏈
        action.release()
        break
    except:
        time.sleep(3)
#關閉瀏覽器
bro.quit()

options配置屬性:

  • options.add_argument(‘headless’) # 無頭模式
  • options.add_argument(‘window-size={}x{}’.format(width, height)) # 直接配置大小和set_window_size一樣
  • options.add_argument(‘disable-gpu’) # 禁用GPU加速
  • options.add_argument(‘proxy-server={}’.format(self.proxy_server)) # 配置代理
  • options.add_argument(’–no-sandbox’) # 沙盒模式執行
  • options.add_argument(’–disable-setuid-sandbox’) # 禁用沙盒
  • options.add_argument(’–disable-dev-shm-usage’) # 大量渲染時候寫入/tmp而非/dev/shm
  • options.add_argument(’–user-data-dir={profile_path}’.format(profile_path)) # 使用者資料存入指定檔案
  • options.add_argument('no-default-browser-check) # 不做瀏覽器預設檢查
  • options.add_argument("–disable-popup-blocking") # 允許彈窗
  • options.add_argument("–disable-extensions") # 禁用擴充套件
  • options.add_argument("–ignore-certificate-errors") # 忽略不信任證書
  • options.add_argument("–no-first-run") # 初始化時為空白頁面
  • options.add_argument(’–start-maximized’) # 最大化啟動
  • options.add_argument(’–disable-notifications’) # 禁用通知警告
  • options.add_argument(’–enable-automation’) # 通知(通知使用者其瀏覽器正由自動化測試控制)
  • options.add_argument(’–disable-xss-auditor’) # 禁止xss防護
  • options.add_argument(’–disable-web-security’) # 關閉安全策略
  • options.add_argument(’–allow-running-insecure-content’) # 允許執行不安全的內容
  • options.add_argument(’–disable-webgl’) # 禁用webgl
  • options.add_argument(’–homedir={}’) # 指定主目錄存放位置
  • options.add_argument(’–disk-cache-dir={臨時檔案目錄}’) # 指定臨時檔案目錄
  • options.add_argument(‘disable-cache’) # 禁用快取
  • options.add_argument(‘excludeSwitches’, [‘enable-automation’]) # 開發者模式