Python通过Selenium实现自动登录功能(广州摇号系统为例)

作者:IT技术圈子 浏览量:1029   发表于 2023-10-31 12:04 标签:

最近在参与广州的小汽车指标摇号,由于系统每次都需要手动输入验证码,突发奇想,能不能用Python实现自动登录呢?答案是可以的。

先来看看广州小汽车摇号系统的登录界面,长这样:

yyy

上面的登录界面并不复杂,包含三个要素:手机号码、密码、验证码。

一、实现原理

主要有三个方面:

1、通过Web自动化框架,对页面指定元素自动填充

2、正确识别验证码并自动填充

3、点击提交

二、涉及的Python类库

要想实现上述的自动登录功能,需要用到以下类库:

1、Web自动化:Selenium,对页面元素定位、填充、点击

2、图片处理:PIL,对验证码图片进行处理

3、验证码识别:pytesseract,识别验证码

三、类库安装

安装Selenium库:该类库对浏览器进行操作,如:自动打开浏览器、关闭浏览器、打开网页、输入内容、点击等。

pip install selenium

安装PIL库:处理图片,如:打开图片资源文件等。

pip install pillow

安装pytesseract库:OCR识别,识别图片中的文字,会有误差,不一定百分百准确。

pip install pytesseract

四、安装浏览器驱动

由于Selenium不能直接打开浏览器,需要下载一个浏览器对应版本的驱动,Selenium通过这个驱动才能打开浏览器:

这里用的是Chrome浏览器版本为118.0.5993.118

下载Chrome驱动,下载地址,注意,要下载对应版本的:

https://googlechromelabs.github.io/chrome-for-testing/#stable

yyy

下载下来后,不用打开程序文件,找个文件夹放好,配置Path环境变量:

yyy

五、了解登录流程

实现自动登录的前提是要了解页面的登录流程,尝试在摇号系统的登录页面登录时,可以看到:需要输入手机号码、输入密码、输入正码,这里有个地方需要注意的是,验证码输入错误时,会自动刷新验证码图片(不是刷新页面哦)。在验证码输入错误的情况下,需要重试。

六、定位元素

了解登录流程后,需要对元素进行定位,Selenium可通过id、xpath等形式定位,此案例通过xpath进行定位,定位元素的方法如下:

1、定位元素

打开摇号系统登录页面,按F12键打开浏览器控制台,点击左上角的箭头

yyy

然后鼠标点击手机号码输入框,控制台会自动定位到对应的元素

yyy

2、复制xpath

右键对应的元素,复制xpath即可

yyy

密码、验证码输入框定位方法同上。

七、完整Python自动登录代码

from PIL import Image
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

# 不自动关闭浏览器
options = webdriver.ChromeOptions()
options.add_experimental_option('detach', True)

# 打开浏览器
driver = webdriver.Chrome(options=options)

# 访问网页
driver.get("https://apply.jtj.gz.gov.cn/apply/")

# 如果不在标题中表示打开失败
assert u"广州市中小客车指标调控管理信息系统" in driver.title

# 找到用户名输入框
elem_mobile = driver.find_element(By.XPATH,
                                  '/html/body/div/div[2]/div/div[2]/div[1]/div[2]/div[1]/form/div[2]/div/div/input')

# 找到密码输入框
elem_pwd = driver.find_element(By.XPATH,
                               '/html/body/div/div[2]/div/div[2]/div[1]/div[2]/div[1]/form/div[3]/div/div/input')
# 找到验证码输入框
elem_valid_code = driver.find_element(By.XPATH,
                                      '/html/body/div/div[2]/div/div[2]/div[1]/div[2]/div[1]/form/div[4]/div/div['
                                      '1]/input')
# todo 输入手机号码
elem_mobile.send_keys(u"输入你的手机号码")
# todo 输入密码
elem_pwd.send_keys(u"输入你的密码")
count = 0

def get_text():
    global count
    # 找到截图的元素
    element_valid_code_img = driver.find_element(By.XPATH,
                                                 '/html/body/div/div[2]/div/div[2]/div[1]/div[2]/div[1]/form/div[4]/div/div[2]/img')
    # 截图
    element_valid_code_img.screenshot('D:\\yh_captcha.png')
    count = count + 1
    image = Image.open('D:\\yh_captcha.png')

    # 识别图片中的验证码,注意验证码不能保证百分百正确,
    valid_code = pytesseract.image_to_string(image)
    valid_code = valid_code.strip()
    if len(valid_code) == 0 or len(valid_code) != 4:
        # 验证码以及错误了,随便给个让系统刷新验证码重新识别
        valid_code = 'code'

    # 输入验证码
    elem_valid_code.send_keys(valid_code)

get_text()

time.sleep(2)
elem_error_valid_code = driver.find_element(By.XPATH, '/html/body/div[2]/p')
elem_err = driver.find_element(By.CLASS_NAME, 'el-icon-error')
if elem_err.tag_name == 'i':
    if count <= 10:
        elem_valid_code.clear()
        # 验证码错误重试
        get_text()

# 点击登录按钮
driver.find_element(By.XPATH, '/html/body/div/div[2]/div/div[2]/div[1]/div[2]/div[3]').click()

八、测试

运行Python脚本,将会自动打开浏览器并登录。