selenium+超级鹰实现模拟登录12306


Posted in Python onJanuary 24, 2021

最近迷上了用selenium去登陆各大网站,别说selenium真挺好用,可以轻松搞定ajax动态加载的网页,不用很费劲的去抓包查找。咳咳…跑题了,回归正题。

这次用selenium去登录12306网站,听说比较困难。我就去试了试,发现它的验证码实在是那啥…就是这样的。听头疼的。

selenium+超级鹰实现模拟登录12306

我来说说主要的代码编写吧。

过程:

用我们的开发者工具定位到输入账号和密码的窗口,找到并send_keys

driver.find_element_by_id('username').send_keys('用户名')
time.sleep(0.5)
driver.find_element_by_id('password').send_keys('密码')

然后复杂的过程就来了。我们想要得到验证码的图片。但是头疼的是,图片是再变化的。我们请求一次,就变化一次,不像其他普通网站一样不会变化,直接保存图片就行了。但是这是12306诶,哪这么轻松。想了想,我决定把整张页面截屏保存下来,然后对验证码区域裁剪下来,就可以保证一致了。

# 将页面进行截图并保存
driver.save_screenshot('12306登录页面截图.png')

# 确定验证码左上角和右下角的坐标
code_img = driver.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
location = code_img.location # 确定验证码图片左上角的坐标
print('location:', location)
size = code_img.size # 确定验证码图片的长和宽
print('size:', size)
rangle = (int(location['x']), int(location['y']), int(location['x']) + int(size['width']),
     int(location['y']) + int(size['height']))
print('rangle:', rangle)
i = Image.open('12306页面截图.png')
# 对指定区域裁剪
code_pic = i.crop(rangle)
file_name = 'code_pic.png'
code_pic.save(file_name)
time.sleep(2)
print('验证码图片保存成功!!')

我们识别验证码用的是超级鹰,具体如何使用可以去查一查。验证码有可能需要我们点击多个,所以通过打码平台会得到多个坐标,就比如这种。有两个日历,需要点击两次,通过超级鹰就会得到两个坐标。如下图。我们发现有两个坐标会有一个“|”,有三个坐标就有两个“|”,所以我们就把他们split下,让每个坐标嵌套再一个列表里。此过程代码如下:

# 识别验证坐标
chaojiying = Chaojiying_Client('用户账号', '密码', '开发者账号') # 用户中心>>软件ID 生成一个替换 96001
im = open('code_pic.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
result = chaojiying.PostPic(im, 9004)['pic_str'] # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()

all_list = [] # 存储被点击的坐标
if '|' in result:
  list1 = result.split('|')
  xy_list = []
  count1 = len(list1)
  for i in list1:
    x = int(list1[i].split(',')[0])
    xy_list.append(x)
    y = int(list1[i].split(',')[1])
    xy_list.append(y)
    all_list.append(xy_list)
else:
  xy_list = []
  x = int(result.split(',')[0])
  xy_list.append(x)
  y = int(result.split(',')[1])
  xy_list.append(y)
  all_list.append(xy_list)
print(all_list)

selenium+超级鹰实现模拟登录12306

selenium+超级鹰实现模拟登录12306

最后嘛,我们得到了验证码的坐标,当然就去点击啦。但是,这个坐标是相对于验证码的图片的坐标,我们必须用ActionChains来移动一下动作链的位置。把他移动到验证码图片的location。,然后点击就ok了。此步骤的代码如下:

# 循环遍历点击图片
for i in all_list:
  x = i[0]
  y = i[1]
  action = ActionChains(driver).move_to_element_with_offset(code_img, x, y).click().perform()
  time.sleep(1)
driver.find_element_by_id('loginSub').click()

最后来看看全部代码吧!!

这个代码是超级鹰提供的接口。我封装成一个类了。

#!/usr/bin/env python
# coding:utf-8

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

下面是自己写的,也就六七十行。

from selenium import webdriver
from chaojiying_Python.chaojiying import Chaojiying_Client
import time
from PIL import Image
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options

# 实现无可视化界面的操作
# chrome_options = Options()
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome('D:\software\studySoftware\chromedriver_win32\chromedriver.exe')
driver.get('https://kyfw.12306.cn/otn/login/init')
# driver.maximize_window()
time.sleep(1)
driver.find_element_by_id('username').send_keys('用户名')
time.sleep(0.5)
driver.find_element_by_id('password').send_keys('密码')
# 将页面进行截图并保存
driver.save_screenshot('12306登录页面截图.png')

# 确定验证码左上角和右下角的坐标
code_img = driver.find_element_by_xpath('//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img')
location = code_img.location # 确定验证码图片左上角的坐标
print('location:', location)
size = code_img.size # 确定验证码图片的长和宽
print('size:', size)
rangle = (int(location['x']), int(location['y']), int(location['x']) + int(size['width']),
     int(location['y']) + int(size['height']))
print('rangle:', rangle)
i = Image.open('12306页面截图.png')
# 对指定区域裁剪
code_pic = i.crop(rangle)
file_name = 'code_pic.png'
code_pic.save(file_name)
time.sleep(2)
print('验证码图片保存成功!!')
# 识别验证坐标
chaojiying = Chaojiying_Client('用户账号', '密码', '开发者账号') # 用户中心>>软件ID 生成一个替换 96001
im = open('code_pic.png', 'rb').read() # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
result = chaojiying.PostPic(im, 9004)['pic_str'] # 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()

all_list = [] # 存储被点击的坐标
if '|' in result:
  list1 = result.split('|')
  xy_list = []
  count1 = len(list1)
  for i in list1:
    x = int(list1[i].split(',')[0])
    xy_list.append(x)
    y = int(list1[i].split(',')[1])
    xy_list.append(y)
    all_list.append(xy_list)
else:
  xy_list = []
  x = int(result.split(',')[0])
  xy_list.append(x)
  y = int(result.split(',')[1])
  xy_list.append(y)
  all_list.append(xy_list)
print(all_list)
# 循环遍历点击图片
for i in all_list:
  x = i[0]
  y = i[1]
  action = ActionChains(driver).move_to_element_with_offset(code_img, x, y).click().perform()
  time.sleep(1)
driver.find_element_by_id('loginSub').click()

到此这篇关于selenium+超级鹰实现模拟登录12306的文章就介绍到这了,更多相关selenium 模拟登录12306内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python使用urllib2获取网络资源实例讲解
Dec 02 Python
python3+PyQt5实现自定义窗口部件Counters
Apr 20 Python
python实现超市扫码仪计费
May 30 Python
caffe binaryproto 与 npy相互转换的实例讲解
Jul 09 Python
python3模拟实现xshell远程执行liunx命令的方法
Jul 12 Python
基于python判断目录或者文件代码实例
Nov 29 Python
基于python plotly交互式图表大全
Dec 07 Python
python爬虫模拟浏览器访问-User-Agent过程解析
Dec 28 Python
python闭包与引用以及需要注意的陷阱
Sep 18 Python
python实现模拟器爬取抖音评论数据的示例代码
Jan 06 Python
pytorch常用数据类型所占字节数对照表一览
May 17 Python
Python 一键获取电脑浏览器的账号密码
May 11 Python
使用numpngw和matplotlib生成png动画的示例代码
Jan 24 #Python
详解如何修改jupyter notebook的默认目录和默认浏览器
Jan 24 #Python
详解修改Anaconda中的Jupyter Notebook默认工作路径的三种方式
Jan 24 #Python
浅析python字符串前加r、f、u、l 的区别
Jan 24 #Python
python 图像增强算法实现详解
Jan 24 #Python
详解用 python-docx 创建浮动图片
Jan 24 #Python
Python爬虫入门教程02之笔趣阁小说爬取
Jan 24 #Python
You might like
php strstr查找字符串中是否包含某些字符的查找函数
2010/06/03 PHP
php表单提交问题的解决方法
2011/04/12 PHP
linux环境apache多端口配置虚拟主机的方法深入介绍
2013/06/09 PHP
javascript some()函数用法详解
2014/11/13 PHP
javascript之大字符串的连接的StringBuffer 类
2007/05/08 Javascript
js 替换功能函数,用正则表达式解决,js的全部替换
2010/12/08 Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
2011/12/12 Javascript
关于eval 与new Function 到底该选哪个?
2013/04/17 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
Javascript节点关系实例分析
2015/05/15 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
JavaScript希尔排序、快速排序、归并排序算法
2016/05/08 Javascript
js 截取或者替换字符串中的数字实现方法
2016/06/13 Javascript
JavaScript实现开关等效果
2017/09/08 Javascript
详解vue中组件参数
2018/07/09 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
2018/10/26 jQuery
jQuery表单元素过滤选择器用法实例分析
2019/02/20 jQuery
浅谈Node 异步IO和事件循环
2019/05/05 Javascript
[01:03:42]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
2016/03/30 Python
python使用两种发邮件的方式smtp和outlook示例
2017/06/02 Python
python中pytest收集用例规则与运行指定用例详解
2019/06/27 Python
浅析Python 简单工厂模式和工厂方法模式的优缺点
2020/07/13 Python
浅谈django不使用restframework自定义接口与使用的区别
2020/07/15 Python
利用python查看数组中的所有元素是否相同
2021/01/08 Python
EQVVS官网:设计师男装和女装
2018/10/24 全球购物
《狐假虎威》教学反思
2014/02/07 职场文书
四查四看剖析材料
2014/02/14 职场文书
母亲节感恩寄语
2014/02/21 职场文书
社区三八妇女节活动总结
2015/02/06 职场文书
校运会通讯稿
2015/07/18 职场文书
再次探讨go实现无限 buffer 的 channel方法
2021/06/13 Golang
windows server2016安装oracle 11g的图文教程
2022/07/15 Servers
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript
前端框架ECharts dataset对数据可视化的高级管理
2022/12/24 Javascript