python自动登录12306并自动点击验证码完成登录的实现源代码


Posted in Python onApril 25, 2018

以下代码可自动登录12306 - 包括输入用户名密码以及自动识别验证码并点击验证码登陆。该源码需要稍作修改:

把  username.send_keys('xxxxxxx')  中的  xxxxxx 改为 你自己的12306账号。

把  password.send_keys('yyyyyy')     中的 yyyyy 改为自己的 12306 密码。

即可运行。

该源码把自动抢票的核心功能:识别验证码并点击验证码登陆实现了。

把代码稍作加工,即可变为自己的自动抢票代码。

运行环境 - 需要安装python运行环境,selenium,requests,浏览器默认为chrome。

运行时 程序会自动分析并识别验证码并点击验证码,完成登陆过程。。。

详细代码如下:

#12306 自动打开12306网站,并输入用户名、密码和验证码,并登录12306,
#author bigluo
#email: 3490699170@qq.com
#coding=utf-8
from selenium import webdriver
import time
from PIL import Image
from selenium.webdriver.common.action_chains import ActionChains
import os
import requests
import numpy
#指定button id和button文本值,并点击,连续点击5次
#return:
#0 click successfully
#-1 连续5次均failed
#1 txt != dest_text,所以不点击
def click_button(b,id,dest_text,j):  #在当前页面查找并点击指定text,错误返回 -1.连续5次,错误时延时1秒
 txt=''
 for i in range(0,5):
  try:
   txt=b.find_element_by_id(id).text
   if txt == dest_text:
    b.find_element_by_id(id).click()
    return 0 
   else:
    return 1
  except:
   time.sleep(1)
   continue
 return -1       #5次都失败了
#给定button id和text,find a given text
#0 found
#-1 not found
def find_button(b,id,dest_text):
 txt=''
 try:
   txt=b.find_element_by_id(id).text
   if txt == dest_text:
    return 0
 except:  
   #print("find_button Error --page txt is "+txt+" input text is "+dest_text)
   return -1
 return -1
#click refresh pic button
def click_refresh(b):
 try:
  b.find_element_by_xpath("//*[@id='loginForm']/div/ul[2]/li[4]/div/div/div[1]").click()
 except:
  print("click_refresh:exception!!!!")
#初始化浏览器 
def init_browser(b):
 b.maximize_window()
#进入登录页,必须是未登录状态
# 0 : 成功
#-1 : 出错了
def visit_login_page(b):
 url = 'https://kyfw.12306.cn/otn/index/init'
 b.get(url)
 if find_button(b,u"login_user",u"登录") != 0: #没退出
  click_button(b,u"regist_out",u"退出",0)  #点击退出
  time.sleep(5)         #休息5秒再查看是否退出
 if click_button(b,u"login_user",u"登录",0) != 0: #点击登陆按钮
  return -1     #Error happened!!
 time.sleep(10)     #访问login page后休息10秒,等待验证码图片加载完成 
 return 0
#截取一张验证码图片,保存为aa.png
def get_a_verify_pic(b):
 imgelement=b.find_element_by_xpath("//*[@id='loginForm']/div/ul[2]/li[4]/div/div/div[3]")
 location = imgelement.location #获取验证码x,y轴坐标 
 size=imgelement.size #获取验证码的长宽
 rangle=(int(location['x']),int(location['y']),int(location['x']+size['width']),int(location['y']+size['height'])) #写成我们需要截取的位置坐标
 b.save_screenshot('aa.png')
 i=Image.open("aa.png") #打开截图
 pic_name='verify_code'+".jpg" #标准12306验证图片
 frame4=i.crop(rangle) #使用Image的crop函数,从截图中再次截取我们需要的区域
 frame4.save(pic_name)
 return pic_name
#破解图片验证码
def ana_pic(b,pic_name):
 body_list=[]
 url='''http://littlebigluo.qicp.net:47720/'''
 files={'file':(pic_name,open(pic_name,'rb'),'image/png')}
 res=requests.post(url,files=files)    #post pic
 if res.status_code == 200:      #return ok
  try:
   #print(res.text)
   if u"文字应该" in res.text:    #识别验证码成功    
    body_str_1=res.text.split(u'''<B>''')
    body_str=body_str_1[2].split(u'<')[0].split()   
    for index in body_str:
     body_list.append(int(index))
    return 0,numpy.array(body_list)
  except:
   print("ana pic failed!!!!")
   return -1,None
 return -1,None     #验证码解析失败
#按输入的下标,点击一张验证码图片
def click_one_pic(b,i):
 try:
  imgelement=b.find_element_by_xpath("//*[@id='loginForm']/div/ul[2]/li[4]/div/div/div[3]")
  if i<=4:
   ActionChains(b).move_to_element_with_offset(imgelement,40+72*(i-1),73).click().perform()
  else:
   i -= 4
   ActionChains(b).move_to_element_with_offset(imgelement,40+72*(i-1),145).click().perform()
 except:
  print("Wa -- click one pic except!!!")
#按bodylist 指示,点击指定验证图片
def click_pic(b,body_list):
 for i in range(len(body_list)):
  click_one_pic(b,body_list[i])
  time.sleep(1)
#输入用户名密码,并点击验证码登陆
#0:login successfully
#1:verify code failed,
#-1 error happened
def login(b):
 pic_name=None
 try:
  pic_name=get_a_verify_pic(b)   #截取12306验证码图片
  ret_val,body_list=ana_pic(b,pic_name) #破解12306验证码
  username=b.find_element_by_id('username')
  username.clear()
  username.send_keys('xxxxxx')
  password=b.find_element_by_id('password')
  password.clear()
  password.send_keys('yyyyyyy') 
  time.sleep(2) 
  if ret_val != 0:
   #print("login : what??? predict return error!!")
   print("login -- no verified pic!!! !!")
   os.remove(pic_name)    #exception occured
   #click_refresh(b)
   return -1
  if len(body_list) == 0:    #no pic recognized
   click_refresh(b)
   print("login : what??? body list is null!!!")
   os.remove(pic_name)    #exception occured
   return 1      #verified failed
  click_pic(b,body_list)
  time.sleep(1)      #休息1秒再点击登陆按钮
  if click_button(b,u"loginSub",u"登录",0) != 0:
   print("login : what??? click button exception!!!")
   return -1     #Error happened!! 
 except:
  if None != pic_name:
   os.remove(pic_name)    #exception occured
  print("login:exception!!")
  return -1
 time.sleep(5)      #查看验证码是否正确??
 ret_val=find_button(b,u"error_msgmypasscode1",u"请点击正确的验证码")
 if ret_val == 0:     #验证码错误
  print("login--Verified code error!!!")
  return 1
 os.remove(pic_name)
 print("login--successfully!!!")
 return 0
#循环login
#返回
#0:登陆成功-正常返回
#-1:登陆失败或异常返回
#1 :验证码未识别出来
def try_login(b):
 for k in range(0,5):     #连续尝试5次
  rt_val=login(b)
  if rt_val < 0:      #error happened
   print("verify got exception!!")
   time.sleep(10)
   continue
  elif rt_val == 1:     #verified code error
   print("verify - code error!!")
   time.sleep(5)
   continue      #login again
  else:        #login successfully
   print("login successfully!!!")
   return 0    
 return -1     #login failed
if __name__ == "__main__": 
 b = webdriver.Chrome()
 init_browser(b)
 visit_login_page(b)
 ret_val = try_login(b) #尝试登录
 if ret_val<0:  
  print("main -- try_login failed!!!") 
 else:
  print("main -- try_login successfully!!!") 
 print("Good job!bigluo!!")

总结

以上所述是小编给大家介绍的python自动登录12306并自动点击验证码完成登录的实现源代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中optparse模块使用浅析
Jan 01 Python
Python处理中文标点符号大集合
May 14 Python
基于scrapy的redis安装和配置方法
Jun 13 Python
Python绘制正余弦函数图像的方法
Aug 28 Python
Python中format()格式输出全解
Apr 12 Python
python画图——实现在图上标注上具体数值的方法
Jul 08 Python
Django REST framework内置路由用法
Jul 26 Python
Python3分析处理声音数据的例子
Aug 27 Python
Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析
Nov 07 Python
Python基础类继承重写实现原理解析
Apr 03 Python
django rest framework 自定义返回方式
Jul 12 Python
pytorch 一行代码查看网络参数总量的实现
May 12 Python
PyQt5实现拖放功能
Apr 25 #Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
Apr 25 #Python
wxPython实现窗口用图片做背景
Apr 25 #Python
django 发送手机验证码的示例代码
Apr 25 #Python
python3+PyQt5实现自定义分数滑块部件
Apr 24 #Python
详解tensorflow载入数据的三种方式
Apr 24 #Python
关于Tensorflow中的tf.train.batch函数的使用
Apr 24 #Python
You might like
PHP实现下载断点续传的方法
2014/11/12 PHP
Symfony2框架学习笔记之HTTP Cache用法详解
2016/03/18 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
javascript实时显示北京时间的方法
2015/03/12 Javascript
jQuery实现表格展开与折叠的方法
2015/05/04 Javascript
jquery实现垂直和水平菜单导航栏
2020/08/27 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
javascript html5轻松实现拖动功能
2017/03/01 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
vue-cli项目如何使用vue-resource获取本地的json数据(模拟服务端返回数据)
2017/08/04 Javascript
ES6中的Promise代码详解
2017/10/09 Javascript
基于vue-router 多级路由redirect 重定向的问题
2018/09/03 Javascript
JS浅拷贝和深拷贝原理与实现方法分析
2019/02/28 Javascript
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
layui输入框中只允许输入整数的实现方法
2019/09/18 Javascript
laydate只显示时分 不显示秒的功能实现方法
2019/09/28 Javascript
node.js express框架实现文件上传与下载功能实例详解
2019/10/15 Javascript
vue下axios拦截器token刷新机制的实例代码
2020/01/17 Javascript
微信小程序收藏功能的实现代码
2020/06/19 Javascript
vue中父子组件传值,解决钩子函数mounted只运行一次的操作
2020/07/27 Javascript
jquery简易手风琴插件的封装
2020/10/13 jQuery
python实现字典(dict)和字符串(string)的相互转换方法
2017/03/01 Python
python中使用zip函数出现错误的原因
2018/09/28 Python
python异步存储数据详解
2019/03/19 Python
python中的decimal类型转换实例详解
2019/06/26 Python
在pycharm下设置自己的个性模版方法
2019/07/15 Python
django的聚合函数和aggregate、annotate方法使用详解
2019/07/23 Python
详解Python中的分支和循环结构
2020/02/11 Python
Python装饰器如何实现修复过程解析
2020/09/05 Python
python 两种方法删除空文件夹
2020/09/29 Python
HTML table 表格边框的实现思路
2019/10/12 HTML / CSS
英国领先的露营和露营车品牌之一:OLPRO
2019/08/06 全球购物
初中学生评语大全
2014/04/24 职场文书
硕士研究生就业推荐信
2014/05/18 职场文书
关于工作时间玩手机的检讨书
2014/09/18 职场文书
信息合作协议书
2014/10/09 职场文书