51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2215|回复: 3
打印 上一主题 下一主题

[selenium] 使用selenium解决12306的登录问题

[复制链接]
  • TA的每日心情
    无聊
    3 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2021-8-16 11:03:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
     最近接触了一些selenium模块的相关知识,觉得还挺有意思的,于是决定亲自尝试写一些爬虫程序来强化selenium模块(一定要多尝试、多动手、多总结)。本文主要使用python爬虫来模拟登录铁路12306官网。这儿得吐槽一句,铁路12306网站的反爬机制做的还是比较好。特别是12306的验证码很是令人很头疼的事,有时候自己去验证都不一定能通过。接下来就使用selenium模块解决验证码。

    实现过程
      首先通过selenium创建一个浏览器,并通过向页面嵌入js代码去掉webdriver控件(我前面有讲过,不懂的大神们可以去看我写的文章)如果不嵌入js代码就会被webdriver控件检测出,不管你怎么滑动滑块都是失败的。


    1. # 绕过window.navigator.webdriver控件检测
    2.   option = Options()
    3.   option.add_experimental_option('excludeSwitches', ['enable-automation'])
    4.   option.add_argument('--disable-blink-features=AutomationControlled')
    5.   
    6.   driver = webdriver.Chrome(options=option)
    7.   driver.maximize_window()
    8.   
    9.   # 切换到账号密码登录窗口
    10.   driver.get('https://kyfw.12306.cn/otn/resources/login.html')
    11.   time.sleep(3)
    12.   driver.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
    13.   time.sleep(2)
    复制代码
    嵌入js代码这样就不会被12306检测到是使用selenium自动化登录了。
      我们先解决最难的验证码。为了实现自动化登录我们使用超级鹰打码平台。
      · 注册并登录超级鹰账号:点击链接进行注册https://www.chaojiying.com/user/login/
      · 点击购买题分,并进行充值;
      · 点击软件id,创建一个软件Id(程序中会用到);
      自动去帮我们去识别验证码。

    1. # 初始化超级鹰
    2.   chaojiying = Chaojiying_Client('超级鹰账号', '超级鹰密码', '软件ID')  # 没有软件ID的可以去自己在超级鹰平台生成
    3.   
    4.   # 处理验证码
    5.   code_img_element = driver.find_element_by_xpath('//*[@id="J-loginImg"]')  # 定位到验证码的位置
    6.   # 用超级鹰去识别验证码
    7.   dic = chaojiying.PostPic(code_img_element.screenshot_as_png, 9004)  # 定位验证码并截图,调用chaojiying里的PostPic类;9004是验证码类型
    8.   result = dic['pic_str']  # x1,y1|x2,y2;超级鹰返回回来的数据是json格式的
    9.   rs_list = result.split("|")
    10.   for rs in rs_list:
    11.       p_temp = rs.split(",")
    12.       x = int(p_temp[0])  # 拿到的是"x"而不是x
    13.       y = int(p_temp[1])
    14.       # 要让鼠标移动到某一个位置,然后进行点击
    15.       ActionChains(driver).move_to_element_with_offset(code_img_element, x, y).click().perform()  # 提交事件;以element为原点移动鼠标去点击验证码
    复制代码
    验证码有可能需要我们点击多个,所以通过打码平台会得到多个坐标,就比如这种,需要点击两次,通过超级鹰就会得到两个坐标。如下图。我们发现有两个坐标会有一个“|”,有三个坐标就有两个“|”,所以我们就把他们split下,让每个坐标嵌套再一个列表里。我们得到了验证码的坐标,下一步就是去点击验证码。但是,这个坐标是相对于验证码的图片的坐标,我们必须用ActionChains来移动一下动作链的位置。详细的输出过程如下图:


    最最后就是比较简单的传输账号密码登录了。
    1. # 输入用户名和密码
    2.   driver.find_element_by_xpath('//*[@id="J-userName"]').send_keys('账号')
    3.   driver.find_element_by_xpath('//*[@id="J-password"]').send_keys('密码')
    4.   # 点击登录按钮
    5.   driver.find_element_by_xpath('//*[@id="J-login"]').click()
    6.   time.sleep(4)
    7.   
    8.   # 移动滑块
    9.   btn = driver.find_element_by_xpath('//*[@id="nc_1_n1z"]')
    10.   ActionChains(driver).drag_and_drop_by_offset(btn, 300, 0).perform()  # 拖拽滑块向右移动300像素
    复制代码
    这个代码是超级鹰提供的接口。我封装成一个类了。

    1.  #!/usr/bin/env python
    2.   # coding:utf-8
    3.   
    4.   import requests
    5.   from hashlib import md5
    6.   
    7.   class Chaojiying_Client(object):
    8.   
    9.       def __init__(self, username, password, soft_id):
    10.           self.username = username
    11.           password =  password.encode('utf8')
    12.           self.password = md5(password).hexdigest()
    13.           self.soft_id = soft_id
    14.           self.base_params = {
    15.               'user': self.username,
    16.               'pass2': self.password,
    17.               'softid': self.soft_id,
    18.           }
    19.           self.headers = {
    20.               'Connection': 'Keep-Alive',
    21.               'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
    22.           }
    23.   
    24.       def PostPic(self, im, codetype):
    25.           """
    26.           im: 图片字节
    27.           codetype: 题目类型 参考 http://www.chaojiying.com/price.html
    28.           """
    29.           params = {
    30.               'codetype': codetype,
    31.           }
    32.           params.update(self.base_params)
    33.           files = {'userfile': ('ccc.jpg', im)}
    34.           r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
    35.           return r.json()
    36.   
    37.       def ReportError(self, im_id):
    38.           """
    39.           im_id:报错题目的图片ID
    40.           """
    41.           params = {
    42.               'id': im_id,
    43.           }
    44.           params.update(self.base_params)
    45.           r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
    46.           return r.json()
    47.   
    48.   
    49.   if __name__ == '__main__':
    50.       chaojiying = Chaojiying_Client('超级鹰账号', '超级鹰密码', '96001')#用户中心>>软件ID 生成一个替换 96001
    51.       im = open('a.jpg', 'rb').read()# 本地图片文件路径来替换 a.jpg 有时WIN系统须要//
    52.       print(chaojiying.PostPic(im, 1902))# 1902 验证码类型 官方网站>>价格体系 3.4+版 print 后要加()
    复制代码
    下面是selenium登录的代码:

    1. from selenium import webdriver
    2.   import time
    3.   from chaojiying import Chaojiying_Client
    4.   from selenium.webdriver.common.action_chains import ActionChains
    5.   from selenium.webdriver.chrome.options import Options
    6.   
    7.   # 初始化超级鹰
    8.   chaojiying = Chaojiying_Client('超级鹰账号', '超级鹰密码.', '软件ID')
    9.   
    10.   # 绕过window.navigator.webdriver控件检测
    11.   option = Options()
    12.   option.add_experimental_option('excludeSwitches', ['enable-automation'])
    13.   option.add_argument('--disable-blink-features=AutomationControlled')
    14.   
    15.   driver = webdriver.Chrome()
    16.   driver.maximize_window()
    17.   
    18.   driver.get('https://kyfw.12306.cn/otn/resources/login.html')
    19.   time.sleep(3)
    20.   driver.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
    21.   time.sleep(2)
    22.   # 处理验证码
    23.   code_img_element = driver.find_element_by_xpath('//*[@id="J-loginImg"]')
    24.   # 用超级鹰去识别验证码
    25.   dic = chaojiying.PostPic(code_img_element.screenshot_as_png, 9004)
    26.   result = dic['pic_str']  # x1,y1|x2,y2
    27.   rs_list = result.split("|")
    28.   for rs in rs_list:
    29.       p_temp = rs.split(",")
    30.       x = int(p_temp[0])  # 拿到的是"x"而不是x
    31.       y = int(p_temp[1])
    32.       # 要让鼠标移动到某一个位置,然后进行点击
    33.       ActionChains(driver).move_to_element_with_offset(code_img_element, x, y).click().perform()  # 提交事件
    34.   
    35.   # 输入用户名和密码
    36.   driver.find_element_by_xpath('//*[@id="J-userName"]').send_keys('12306账号')
    37.   driver.find_element_by_xpath('//*[@id="J-password"]').send_keys('12306密码')
    38.   # 点击登录按钮
    39.   driver.find_element_by_xpath('//*[@id="J-login"]').click()
    40.   time.sleep(4)
    41.   
    42.   # 移动滑块
    43.   btn = driver.find_element_by_xpath('//*[@id="nc_1_n1z"]')
    44.   ActionChains(driver).drag_and_drop_by_offset(btn, 300, 0).perform()
    复制代码


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏2
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-24 11:10 , Processed in 0.067592 second(s), 26 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表