一、准备工作

1.下载selenium
可以直接

 pip install selenium

2.下载chromedriver
下载浏览器自动化测试工具

二、selenium 访问页面获取验证码

获取验证码需要通过先截取整个页面然后在通过整个页面截取验证码(要注意电脑的显示设置是不是100%)

通过selenium截取整个页面,然后分别获取验证码的左上角location和验证码的大小size再通过PIL模块进行裁剪

def get_captcha():
    # 获取网页的截图
    allscreen = browser.get_screenshot_as_file('allscreen.png')
    # 获取captcha
    captcha = browser.find_element_by_class_name('login-pwd-code')
    # 获取captcha的左上角位置
    location = captcha.location
    # 获取图片大小
    size = captcha.size
    # 裁取captcha
    rangle = (location['x'],location['y'],(location['x']+size['width']),(location['y']+size['height']))
    i = Image.open('./allscreen.png')
    captcha_img = './captcha.png'
    frame = i.crop(rangle)
    frame.save(captcha_img)

三、利用超级鹰获取验证码所对应的位置

1.这里需要先注册一个超级鹰的账号认证后会给1000积分,链接https://www.chaojiying.com/user/login/
2.点击软件id,创建一个软件Id
3.下载示例代码(开发文档—>选择相应的语言–>下载示例demo),python示例代码如下所示:

#!/usr/bin/env python

import requests
from hashlib import md5

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()


if __name__ == '__main__':
	chaojiying = Chaojiying_Client('用户名', '密码', '软件ID')	#用户中心>>软件ID 生成一个替换 96001
	im = open('./captcha.jpg', 'rb').read()													#本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
	print (chaojiying.PostPic(im, 9004))											#1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()

通过超级鹰得到验证码所需点击位置

def click_captcha():
    # 获取验证码需要的为点击位置
    chaojiying = Chaojiying_Client('用户名', '密码', '软件ID')	#用户中心>>软件ID 生成一个替换 96001
	im = open('./captcha.jpg', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    location = chaojiying.PostPic(im, 9004)['pic_str']  # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
    print(chaojiying.PostPic(im, 9004))
    # 将位置进行分割成 [ [ ], [ ], [ ] ]类型
    location_list = [i.split(',') for i in location.split('|')]
    for l in location_list:
        x = l[0]
        y = l[1]
        #点击当前x,y所处位置
        ActionChains(browser).move_to_element_with_offset(browser.find_element_by_class_name('login-pwd-code'), x,
                                                          y).click().perform()
        time.sleep(0.5)

四,解决滑动验证码

这里目前需要在 browser.get(‘https://kyfw.12306.cn/otn/resources/login.html’)后面加入

script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
    browser.execute_script(script)

要不然会验证码会一直报错
因为12306会识别出是使用selenium 登陆的

def slider():
    #滑动验证码
    span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
    # 对div_tag进行滑动操作
    action = ActionChains(browser)
    # 点击长按指定的标签
    action.click_and_hold(span).perform()
    action.drag_and_drop_by_offset(span, 400, 0).perform()
  

下面是完整代码

from selenium import webdriver
from selenium.webdriver import ActionChains
import time
from PIL import Image
import requests
from hashlib import md5
from selenium.webdriver import ChromeOptions
#验证码识别处理
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()
def login(username,password):
# 填写账号密码
browser.find_element_by_id('J-userName').send_keys(username)
browser.find_element_by_id('J-password').send_keys(password)
# 获取验证码
get_captcha()
# 填写验证码
click_captcha()
#点击登录
browser.find_element_by_id('J-login').click()
time.sleep(4)
#滑动验证码
slider()
print('成功登陆')
time.sleep(3)
print(browser.current_url)
def slider():
#滑动验证码
span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
# 对div_tag进行滑动操作
action = ActionChains(browser)
# 点击长按指定的标签
action.click_and_hold(span).perform()
action.drag_and_drop_by_offset(span, 400, 0).perform()
def click_captcha():
# 获取验证码需要的为点击位置
chaojiying = Chaojiying_Client('用户名', '密码', '软件id')  # 用户中心>>软件ID 生成一个替换 96001
im = open('./captcha.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
location = chaojiying.PostPic(im, 9004)['pic_str']  # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
print(chaojiying.PostPic(im, 9004))
# 将位置进行分割成 [ [ ], [ ], [ ] ]类型
location_list = [i.split(',') for i in location.split('|')]
for l in location_list:
x = l[0]
y = l[1]
ActionChains(browser).move_to_element_with_offset(browser.find_element_by_class_name('login-pwd-code'), x,
y).click().perform()
time.sleep(0.5)
def get_captcha():
# 获取网页的截图
allscreen = browser.get_screenshot_as_file('allscreen.png')
# 获取captcha
captcha = browser.find_element_by_class_name('login-pwd-code')
# 获取captcha的左上角位置
location = captcha.location
# 获取图片大小
size = captcha.size
# 裁取captcha
rangle = (location['x'],location['y'],(location['x']+size['width']),(location['y']+size['height']))
i = Image.open('./allscreen.png')
captcha_img = './captcha.png'
frame = i.crop(rangle)
frame.save(captcha_img)
if __name__ == '__main__':
#防止被服务器识别
option = ChromeOptions()  # 实例化一个ChromeOptions对象
option.add_experimental_option('excludeSwitches', ['enable-automation'])  # 以键值对的形式加入参数
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
# 获取响应
browser.get('https://kyfw.12306.cn/otn/resources/login.html')
#防止被12306识别为selenium登陆
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
browser.execute_script(script)
#屏幕最大化
browser.maximize_window()
time.sleep(1)
# 点击账号登陆
browser.find_element_by_class_name('login-hd-account').click()
login('用户名','密码')

本文地址:https://blog.csdn.net/qq_38977435/article/details/110905216