python+selenium实现12306模拟登录的步骤


Posted in Python onJanuary 21, 2021

简介:

这里是利用了selenium+图片识别验证,来实现12306的模拟登录,中间也参考了好几个项目,实现了这个小demo,中间也遇到了很多的坑,主要难点在于图片识别和滑动验证这两个方面,图片识别是利用超级鹰的服务进行验证识别的,其次一个难点就是在账户密码和图片识别都过了以后的滑动验证,因为12306网站做了反爬,利用selenium滑动时,会报错,提示你一直刷新,这里也是更改了滑动框。

技术栈:

python、selenium、图片验证、滑动验证

思路:

提前卧槽,12306网站的并发真的牛逼。

在模拟登录的时候,第一个难点就是图片验证,这里不会底层的算法,只能通过图片识别平台的api接口服务进行解密,返回验证坐标以后,通过selenium的点击动能,进行点击,在这里提前说明一下,网上有很多项目在实例化浏览器时,需要调整桌面分辨率,然后最大化窗口,这样截屏才不会出现截不全的情况,我这边是比较省事的,直接用xpath定位到验证码的png文件。直接写入到本地,然后传到图片识别平台进行识别。

里面涉及了一些selenium的方法,我基本上都是现查现用,比如按住鼠标不放、按左键什么的。

具体的代码和注解贴在下面,

from selenium import webdriver
from hashlib import md5
import requests
import time
from selenium.webdriver import ActionChains
 
#  这个类是超级鹰平台写的调用服务的接口代码,也是比较容易看懂的
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()
 
#   这里进入模拟登录的主程序
 
# 实例化浏览器,并且最大化。然后请求12306主网站,我这里是从首页请求的,大家可以直接从登陆页面请求
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('http://12306.cn/')
time.sleep(5)
# 因为是从首页请求的,所以下面有两个点击的动作,都是为了点进登陆页面
browser.find_element_by_xpath('//*[@id="J-header-login"]/a[1]').click()
time.sleep(0.3)
# 这里比较重要了,这里就是利用这个代码,来更改selenium中的滑动功能,让网站不报错
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
browser.execute_script(script)
time.sleep(1)
# 这里进入帐号登录
browser.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
time.sleep(0.3)
#  这里直接定位验证码的png文件,然后保存
img = browser.find_element_by_xpath('//*[@id="J-loginImg"]')
img.screenshot('cde.png')
# 调用超级鹰的参数
chaojiying = Chaojiying_Client('用户名', '密码', 'ID')#  这个在超级鹰的实例代码中有解释
im = open('../12306/cde.png', 'rb').read()
# 注意,这里返回的是一个字典格式,所以直接取要用的key,来返回坐标
result = chaojiying.PostPic(im, 9004)['pic_str']
print(result)
# 这里就是处理超级鹰返回坐标的方法了
all_list = []
# 通过判断超级鹰返回坐标的格式进行坐标处理,
# 返回的坐标有两种形式,一种是以|隔开的,一种是用,隔开的,对应下面两种处理方式
# 处理好的坐标存入list
if '|' in result:
    list = result.split('|')
    for i in range(len(list)):
        x_y = []
        x = int(list[i].split(',')[0])
        y = int(list[i].split(',')[1])
        x_y.append(x)
        x_y.append(y)
        all_list.append(x_y)
else:
    x_y = []
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    x_y.append(x)
    x_y.append(y)
    all_list.append(x_y)
print(all_list)
 
# 处理好的坐标进行循环,并带入selenium进行点击点击
for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(browser).move_to_element_with_offset(
        img, x, y).click().perform()
    time.sleep(0.5)
# 图片点击好以后,向表单内发送账户密码
browser.find_element_by_xpath('//*[@id="J-userName"]').send_keys('账号')
browser.find_element_by_xpath('//*[@id="J-password"]').send_keys('密码')
# 进行点击登录按钮
browser.find_element_by_xpath('//*[@id="J-login"]').click()
time.sleep(2)
# 下面就是滑动模块了
# 上面已经更改过selenium的滑动模块,所以这里就可以直接定位到按钮的位置,进行点击滑动
span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
action = ActionChains(browser)
# 这里是selenium的方法,按住点击不放
action.click_and_hold(span)
# 下面就是滑动了
action.drag_and_drop_by_offset(span,400,0).perform()
# 这里加了个循环,就是滑动不行,一直刷新继续滑动,直到成功
# 其实这里也只是为了保险起见,因为上面改了滑动框,基本上都会成功
while True:
    try:
        info=browser.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span').text
        print(info)
        if info=='哎呀,出错了,点击刷新再来一次':
            #点击刷新
            browser.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span/a').click()
            time.sleep(0.2)
            #重新移动滑块
            span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
            action = ActionChains(browser)
            # 点击长按指定的标签
            action.click_and_hold(span).perform()
            action.drag_and_drop_by_offset(span, 400, 0).perform()
            time.sleep(5)
    except:
        print('ok!')
        break
# 完成后,松开鼠标
action.release()
 
time.sleep(5)
# 退出
browser.quit()

最后想说的是

实现抢票的事,这个我还暂时没想好怎么去做

平时工作比较忙

所以以后实现这个功能吧

拜拜~

以上就是python+selenium实现12306模拟登录的步骤的详细内容,更多关于python 12306模拟登录的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python基础教程之分支、循环简单用法
Jun 16 Python
发布你的Python模块详解
Sep 15 Python
python中matplotlib实现最小二乘法拟合的过程详解
Jul 11 Python
python类的方法属性与方法属性的动态绑定代码详解
Dec 27 Python
python 使用re.search()筛选后 选取部分结果的方法
Nov 28 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
libreoffice python 操作word及excel文档的方法
Jul 04 Python
kali中python版本的切换方法
Jul 11 Python
django正续或者倒序查库实例
May 19 Python
编写python代码实现简单抽奖器
Oct 20 Python
Python Selenium XPath根据文本内容查找元素的方法
Dec 07 Python
详细介绍python类及类的用法
May 31 Python
python基于爬虫+django,打造个性化API接口
Jan 21 #Python
Python 无限级分类树状结构生成算法的实现
Jan 21 #Python
python 制作网站筛选工具(附源码)
Jan 21 #Python
python使用scapy模块实现ping扫描的过程详解
Jan 21 #Python
Python 中如何使用 virtualenv 管理虚拟环境
Jan 21 #Python
python使用scapy模块实现ARP扫描的过程
Jan 21 #Python
Python3利用scapy局域网实现自动多线程arp扫描功能
Jan 21 #Python
You might like
深入理解PHP原理之异常机制
2010/08/21 PHP
php笔记之常用文件操作
2010/10/12 PHP
PHP生成数组再传给js的方法
2014/08/07 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
php面试中关于面向对象的相关问题
2019/02/13 PHP
php解决crontab定时任务不能写入文件问题的方法分析
2019/09/16 PHP
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
js使用正则实现ReplaceAll全部替换的方法
2014/07/18 Javascript
jQuery 重复加载错误以及修复方法
2014/12/16 Javascript
JS中处理时间之setUTCMinutes()方法的使用
2015/06/12 Javascript
JS实现很实用的对联广告代码(可自适应高度)
2015/09/18 Javascript
原生js仿jquery一些常用方法(必看篇)
2016/09/20 Javascript
JS数组搜索之折半搜索实现方法分析
2017/03/27 Javascript
JS解决移动web开发手机输入框弹出的问题
2017/03/31 Javascript
node.js express中app.param的用法详解
2017/07/16 Javascript
js实现以最简单的方式将数组元素添加到对象中的方法
2017/12/20 Javascript
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
vue在自定义组件中使用v-model进行数据绑定的方法
2019/03/25 Javascript
NodeJs生成sitemap站点地图的方法示例
2019/06/11 NodeJs
[00:32]2018DOTA2亚洲邀请赛VGJ.T出场
2018/04/03 DOTA
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
python模块之re正则表达式详解
2017/02/03 Python
python flask安装和命令详解
2019/04/02 Python
python面向对象法实现图书管理系统
2019/04/19 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
python之yield和Generator深入解析
2019/09/18 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
Python3.7下安装pyqt5的方法步骤(图文)
2020/05/12 Python
使用Keras训练好的.h5模型来测试一个实例
2020/07/06 Python
沃达丰英国有限公司:Vodafone英国
2019/04/16 全球购物
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
关于感恩的歌曲整理(8首)
2019/08/14 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python
Python 中 Shutil 模块详情
2021/11/11 Python
JavaScript数组 几个常用方法总结
2021/11/11 Javascript