suyinchuo 发表于 2019-11-5 11:49

利用requests和selenium实现调用接口识别验证码并登陆12306

本帖最后由 suyinchuo 于 2019-11-5 11:53 编辑

今天突发奇想做了一个12306自动登陆的程序!selenium环境配置:https://www.cnblogs.com/whyan/p/9206467.html
调用了接口http://littlebigluo.qicp.net:47720/ 大家酌情使用!

大概思路:

[*]使用selenium库操作浏览器打开登陆页面并输入用户名和密码    def login(self):
      # 初始化浏览器对象
      driver = webdriver.Chrome()
      # 12306登陆页面
      login_url = "https://kyfw.12306.cn/otn/resources/login.html"
      # 设置浏览器长宽
      driver.set_window_size(1200, 900)
      # 打开登陆页面
      driver.get(login_url)
      # 找到账号登陆按钮
      account = driver.find_element_by_class_name("login-hd-account")
      # 点击按钮
      account.click()
      # 找到用户名输入框
      userName = driver.find_element_by_id("J-userName")
      # 输入用户名
      userName.send_keys(self.username)
      # 找到密码输入框
      passWord = driver.find_element_by_id("J-password")
      # 输入密码
      passWord.send_keys(self.password)
[*]获取验证码图片,并保存到本地    def getVerifyImage(self):
      try:
            # 找到图片验证码标签
            img_element = WebDriverWait(self.driver, 100).until(
                EC.presence_of_element_located((By.ID, "J-loginImg"))
            )

      except Exception as e:
            print(u"验证码图片未加载!")
      # 获取图片验证码的src属性,就是图片base64加密后的数据
      base64_str = img_element.get_attribute("src").split(",")[-1]
      # base64解码得到图片的数据
      imgdata = base64.b64decode(base64_str)
      # 存入img.jpg
      with open('img.jpg', 'wb') as file:
            file.write(imgdata)
[*]调用接口识别验证码图片,此技术基于深度学习,本人技术有限,暂不讲解!    def getVerifyResult(self):
      # 12306验证码识别网址
      url = "http://littlebigluo.qicp.net:47720/"
      # 发送post请求把图片数据带上
      response = requests.request("POST", url, data={"type": "1"}, files={'pic_xxfile': open('img.jpg', 'rb')})
      result = []
      print(response.text)
      # 返回识别结果
      for i in re.findall("<B>(.*)</B>", response.text).split(" "):
            result.append(int(i) - 1)
[*]根据结果选择图片验证码点击    def moveAndClick(self):
      try:
            # 创建鼠标对象
            Action = ActionChains(self.driver)
            for i in self.result:
                # 根据获取的结果取坐标选择图片并点击
                Action.move_to_element(self.img_element).move_by_offset(self.coordinate,
                                                                        self.coordinate).click()
            Action.perform()
      except Exception as e:
            print(e)
[*]点击登陆按钮    def submit(self):
      # 点击登陆按钮
      self.driver.find_element_by_id("J-login").click()

附完整代码
import base64
import re
import time

import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class Login(object):
    def __init__(self, username, password):
      # 图片验证码坐标
      self.coordinate = [[-105, -20], [-35, -20], , , [-105, 50], [-35, 50], , ]
      self.username = username
      self.password = password
    def login(self):
      # 初始化浏览器对象
      driver = webdriver.Chrome()
      # 12306登陆页面
      login_url = "https://kyfw.12306.cn/otn/resources/login.html"
      # 设置浏览器长宽
      driver.set_window_size(1200, 900)
      # 打开登陆页面
      driver.get(login_url)
      # 找到账号登陆按钮
      account = driver.find_element_by_class_name("login-hd-account")
      # 点击按钮
      account.click()
      # 找到用户名输入框
      userName = driver.find_element_by_id("J-userName")
      # 输入用户名
      userName.send_keys(self.username)
      # 找到密码输入框
      passWord = driver.find_element_by_id("J-password")
      # 输入密码
      passWord.send_keys(self.password)
      self.driver = driver

    def getVerifyImage(self):
      try:
            # 找到图片验证码标签
            img_element = WebDriverWait(self.driver, 100).until(
                EC.presence_of_element_located((By.ID, "J-loginImg"))
            )

      except Exception as e:
            print(u"验证码图片未加载!")
      # 获取图片验证码的src属性,就是图片base64加密后的数据
      base64_str = img_element.get_attribute("src").split(",")[-1]
      # base64解码得到图片的数据
      imgdata = base64.b64decode(base64_str)
      # 存入img.jpg
      with open('img.jpg', 'wb') as file:
            file.write(imgdata)
      self.img_element = img_element

    def getVerifyResult(self):
      # 12306验证码识别网址
      url = "http://littlebigluo.qicp.net:47720/"
      # 发送post请求把图片数据带上
      response = requests.request("POST", url, data={"type": "1"}, files={'pic_xxfile': open('img.jpg', 'rb')})
      result = []
      print(response.text)
      # 返回识别结果
      for i in re.findall("<B>(.*)</B>", response.text).split(" "):
            result.append(int(i) - 1)
      self.result = result
      print(result)

    def moveAndClick(self):
      try:
            # 创建鼠标对象
            Action = ActionChains(self.driver)
            for i in self.result:
                # 根据获取的结果取坐标选择图片并点击
                Action.move_to_element(self.img_element).move_by_offset(self.coordinate,
                                                                        self.coordinate).click()
            Action.perform()
      except Exception as e:
            print(e)

    def submit(self):
      # 点击登陆按钮
      self.driver.find_element_by_id("J-login").click()

    def __call__(self):
      self.login()
      time.sleep(3)
      self.getVerifyImage()
      time.sleep(1)
      self.getVerifyResult()
      time.sleep(1)
      self.moveAndClick()
      time.sleep(1)
      self.submit()
      time.sleep(1000)


if __name__ == '__main__':
    # 用户名和密码
    username = '******'
    password = '******'
    Login(username, password)()


基本的注释都有,不明白的可以参考selenium python文档!!!

欢迎评分打赏~~~谢谢各位~~~

chuange 发表于 2020-12-7 09:32

小飞虫 发表于 2020-12-2 21:35
可以开源吗?

可以的,,但是新版本增加了滑块验证码,,,所以还需要破解滑块验证码先

yc19951005 发表于 2019-11-5 14:04

瑞浩娱乐 发表于 2019-11-5 11:51
12306的验证码都能识别,666,大佬厉害

这是调用第三方的api 识别验证码的

瑞浩娱乐 发表于 2019-11-5 11:51

12306的验证码都能识别,666,大佬厉害

dqlb123 发表于 2019-11-5 11:55

很好,了解了

yike911 发表于 2019-11-5 12:59

suyinchuo 发表于 2019-11-5 16:25

yc19951005 发表于 2019-11-5 14:04
这是调用第三方的api 识别验证码的

是的哦本人技术有限的 只知道第三方通过深度学习实现的识别验证码

随梦期初 发表于 2019-11-10 22:53

过来学习一下

打野不清兵 发表于 2019-11-11 14:46

请问调用图片识别的接口有次数限制吗?

dfg88 发表于 2019-12-13 11:29

很棒,好好学习一下

pythonly123 发表于 2020-2-11 08:44

楼主,好像执行不了!!!
页: [1] 2 3
查看完整版本: 利用requests和selenium实现调用接口识别验证码并登陆12306