我来自北方 跨过山与海 驻足你门外

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’]) # 开发者模式
posted @ 2020-09-22 11:59  SkyRabbit  阅读(212)  评论(0编辑  收藏  举报
您的浏览器不兼容canvas