- 一组连续的操作就是动作链
- 滑动:鼠标点击长按之后进行偏移
1、示例代码引入
from selenium import webdriver
from time import sleep
from selenium.webdriver import ActionChains #动作链
# 实例化一个浏览器对象
bro = webdriver.Chrome(executable_path='./chromedriver.exe')
# 发送请求
bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
sleep(1)
#如果定位的标签是标签嵌套存在于iframe标签之下的,则需要使用switch_to的操作进行标签定位
bro.switch_to.frame('iframeResult')
# 定位标签属性
div_tag = bro.find_element_by_xpath('//*[@id="draggable"]')
# 实例化动作链对象
action = ActionChains(bro)
# 点击且长按一个标签
action.click_and_hold(div_tag)
for i in range(5):
#move_by_offset设置偏移量,perform可以让动作链立即执行
action.move_by_offset(10,10).perform()
# sleep(2)
# 对div_tag进行滑动
bro.quit()
效果GIF图:
2、12306模拟登录
实现流程
可以对登录首页进行截图,在通过裁剪的操作将验证码图片进行获取
验证码图片提交给打码平台进行识别
环境安装:
pip install PIL #进行图片裁剪模块,或者安装pip install Pillow , Pillow是PIL的升级版
pip install selenium
pip install requests
from selenium import webdriver
from time import sleep
from selenium.webdriver import ActionChains #动作链
from PIL import Image
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__':
def transform_codeImg(imgPath,imgType):
chaojiying = Chaojiying_Client('xjs2020', 'xxx', '905940') #超级鹰用户名,密码,ID:超级鹰用户中心>>软件ID 生成一个替换 96001
im = open(imgPath, 'rb').read()#本地图片文件路径 来替换 a.jpg 有时WIN系统须要
return chaojiying.PostPic(im, imgType)['pic_str']#1902 验证码类型
# 实例化一个浏览器对象
bro = webdriver.Chrome(executable_path='./chromedriver.exe')
bro.maximize_window()#浏览器全屏显示
# 发送请求
bro.get('https://kyfw.12306.cn/otn/resources/login.html')
sleep(0.5)
# 点击一下使用账号密码登录
bro.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
sleep(0.5)
# 首页截图
bro.save_screenshot('./main.png')
#将验证码图片进行裁剪
img_tag = bro.find_element_by_xpath('//*[@id="J-loginImg"]')#定位到验证码图标属性
location = img_tag.location #img_tag标签在页面中的起始位置(x,y)
# print(location) #{'x': 712, 'y': 284}
size = img_tag.size #img_tag在页面中显示的尺寸包含长宽
# print(size) #{'height': 188, 'width': 300}
#存储验证码图片左下角和右上角的坐标
rangle = (int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height']))
#根据rangle进行验证码的裁剪
i = Image.open('./main.png')
frame = i.crop(rangle)#根据rangle进行指定区域裁剪
frame.save('./code.png')
#将验证码图片提交给超级鹰
result = transform_codeImg('./code.png',9004)
#将170,70|4,150转换成[[170,70],[4,150]]
all_list = []#[[170,70],[4,150]]
if '|' in result:
list_1 = result.split('|')
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)
for loc in all_list:
x = loc[0]
y = loc[1]
ActionChains(bro).move_to_element_with_offset(img_tag,x,y).click().perform()#通过定位到验证码图标属性进行位置滑动,perform立即执行
#ActionChains(bro).move_by_offset(x,y)#注意:此方法不可取,他是针对整张页面进行滑动
sleep(1)
user_tag = bro.find_element_by_id('J-userName')
user_tag.send_keys('15801500903') #12306用户名
pwd_tag = bro.find_element_by_id('J-password')
pwd_tag.send_keys('xxx') #12306密码
sleep(2)
bro.find_element_by_id('J-login').click()
sleep(6)
bro.quit()
效果GIF图