用python做一个自动签到程序(网页)

时间:2024-03-08 09:53:55

背景:疫情期间,学校要求每天在上午10点之前填报信息。有时容易忘记填报,就会受辅导员惩罚。

我们可以使用网站访问签到页面,所以这里用这个例子来图文演示如何实现自动签到功能

程序中使用到的Python库有:

selenium:selenium是一个用电脑模拟人操作浏览器网页,可以实现自动化,测试等的库。

time:此模块提供各种时间相关功能。会用到其sleep()方法让程序挂起一会儿。

1、准备工作

  1. 这里python使用chrome浏览器来打开网页。就需要安装chrome浏览器的驱动——chromedrive。

    1. 首先康康本电脑chrome浏览器的版本。

      用python做一个自动签到程序_查看chrome版本

      用python做一个自动签到程序_查看chrome版本2

    2. 下载版本对应的浏览器驱动。

      下载位置:https://chromedriver.chromium.org/downloads

      这里咱们下载96.0.4664.45版本

      用python做一个自动签到程序_下载chrome驱动1

      用python做一个自动签到程序_下载chrome驱动2

    3. 将驱动解压放到指定文件夹内。

      用python做一个自动签到程序_解压放到指定文件夹

      解压后,要将文件放到两个位置

      1. chrome文件位置

        用python做一个自动签到程序_chromedriver2

      2. python解释器(Scripts文件夹中)

        用python做一个自动签到程序_当前解释器的位置

        用python做一个自动签到程序_chromedriver

    4. 将chrome文件位置添加到环境变量

      用户变量-->Path 添加chrome浏览器的文件位置

      用python做一个自动签到程序_环境变量

  2. 当驱动配置完成后,试试python是否能自动打开chrome并访问指定url。

用python做一个自动签到程序_成功启动chrome访问url

上图是python成功打开浏览器并访问指定url。那么此时准备工作全部完成。

2、代码实现

以下代码为示例,但核心功能就是这一小段:

from selenium import webdriver
import time
from selenium.webdriver.common.by import By


def sign_in():
    driver = webdriver.Chrome()
    url = \'https://xxxxxx\'
    driver.get(url)

    # 载入到这个网页后,挂起5秒,再继续执行。
    # 挂起5秒是因为加载网页是需要一定时间的,当网页还没完全加载出来时,程序早就执行到下一句了,而下一句代码是		到网页中寻找指定元素。所以,当网页还没加载出来时,程序会因为找不到指定元素而报错。
    time.sleep(5)
    # 用xpath的方式寻找指定元素。
    # confirmElement = driver.find_element_by_xpath(\'//*[@id="CHECK"]/div[2]/div[2]/input\')。
    # 上面的写法在新版本中被selenium弃用了,改用下面的写法。
      confirmElement = driver.find_element(By_XPATH, \'//*[@id="CHECK"]/div[2]/div[2]/input\')
    # 点击指定元素
    confirmElement.click()


if __name__ == \'__main__\':
    sign_in()

这里提一下如何获取元素的xpath:

用python做一个自动签到程序_元素xpath

3、python部分踩过的坑和建议:

曾经也用过这种方法,当时每次都是失败,就是因为没有 time.sleep() 导致程序总是报错 “找不到该元素”

这是个大坑。

所以,在每个点击之前,需要加载的地方都加一个 time.sleep() 会更好,确保能够找到所需元素。

现在,这个程序可以帮你完成点击签到的任务。那么,想要每天自动签到的话就只剩让他定时执行了。

但是要让他每天定时自动执行,自动签到的话,最好将该程序部署到网络服务器上。

4、部署到服务器上

我这里使用了腾讯云服务器。

准备工作:

  • Linux服务器上要安装python 3解释器(python3以上版本)。linux系统安装python3和pip

    用python做一个自动签到程序_Linux安装python3

  • 安装python运行时必要的库。(selenium、time、requests)

    pip3 install selenium
    pip3 install time
    pip3 install requests
    
  • 安装Linux版本的chrome。

    (尝试过安装指定版本的chrome,但是没找到方法,只能安装最新版chrome)

    yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
    
  • 安装chrome必要的库。

    yum install mesa-libOSMesa-devel gnu-free-sans-fonts wqy-zenhei-fonts
    
  • 下载Linux上chrome对应版本的chromedriver,并放入Linux系统中。可以使用 Xftp 从Windows系统将文件传输到Linux服务器上。

    下载位置:https://chromedriver.chromium.org/downloads

    google-chrome --version	#查看chrome版本
    
  • 解压下载的chromedriver。

    unzip chromedriver_linux64.zip
    
  • 将解压的文件放到 /usr/bin/文件夹下

    mv chromedriver /usr/bin
    
  • 给予执行权限

    chmod +x /usr/bin/chromedriver
    

至此,已经能在服务器中执行该自动签到的python程序了。还差最后一步——定时执行

5、定时任务

需要每天自动签到的话,必须让这个程序在每天定时运行一次。Linux上可以直接使用crontab进行定时任务。

crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似

Linux Crontab定时运行python程序

# 每天0点30分定时执行/export/python/Demo.py。(执行必须使用python3全路径,只用python3无反应)
30 0 * * * /usr/local/python3.8/bin/python3 /export/python/Demo.py

6、源码

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
import requests
from selenium.webdriver.common.by import By


def automatic(person):
    chrome_options = Options()
    chrome_options.add_argument(\'--headless\')
    chrome_options.add_argument(\'--disable-gpu\')
    chrome_options.add_argument("window-size=1024,768")
    # 由于是在Linux中运行,没有chrome页面。所以要使用添加沙盒模式(不显示运行)
    chrome_options.add_argument("--no-sandbox")
    driver = webdriver.Chrome(options=chrome_options)
    try:
        url = \'http://dw10.fdzcxy.edu.cn/datawarn/ReportServer?formlet=app/sjkrb.frm&op=h5&userno=\' + person[
            1] + \'#/form\'
        driver.get(url)

        # 载入到这个网页后,睡5秒让页面元素全部加载出来,再继续执行。
        # 不然当页面元素还没加载出来就执行以下代码,会报错。
        time.sleep(5)

        # 选择省份
        province = driver.find_element(By.XPATH, \'//*[@id="SHENG"]/div[2]\')
        province.click()
        time.sleep(3)
        province_input = driver.find_element(By.XPATH,
                                             \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[1]/div/div[1]/div/input\')
        province_input.click()
        time.sleep(3)
        province_input.send_keys(person[2])
        time.sleep(7)
        check = driver.find_element(By.XPATH,
                                    \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[2]/div/div/div/div/div/div[3]/div\')
        check.click()

        time.sleep(5)
        # 选择市
        city = driver.find_element(By.XPATH, \'//*[@id="SHI"]/div[2]\')
        city.click()
        time.sleep(3)
        city_input = driver.find_element(By.XPATH,
                                         \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[1]/div/div[1]/div/input\')
        city_input.click()
        time.sleep(3)
        city_input.send_keys(person[3])
        time.sleep(7)
        check = driver.find_element(By.XPATH,
                                    \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[2]/div/div/div/div/div/div[3]/div\')
        check.click()

        time.sleep(5)
        # 选择市
        counties = driver.find_element(By.XPATH, \'//*[@id="QU"]/div[2]\')
        counties.click()
        time.sleep(3)
        counties_input = driver.find_element(By.XPATH,
                                             \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[1]/div/div[1]/div/input\')
        counties_input.click()
        time.sleep(3)
        counties_input.send_keys(person[4])
        time.sleep(7)
        check = driver.find_element(By.XPATH,
                                    \'//*[@id="app"]/div/div[2]/div/div/div/div/div[2]/div/div[2]/div/div/div/div/div/div[3]/div\')
        check.click()

        time.sleep(5)
        # 点击“承诺”按钮
        confirmElement = driver.find_element(By.XPATH, \'//*[@id="CHECK"]/div[2]/div[2]/input\')
        confirmElement.click()

        time.sleep(5)
        # 点击“提交”按钮
        submitElement = driver.find_element(By.XPATH, \'//*[@id="SUBMIT"]/div[2]\')
        submitElement.click()

        time.sleep(5)
        # 点击“确认”按钮
        lastElement = driver.find_element(By.XPATH, \'//*[@id="app"]/div/div[2]/div/div/div/div[2]\')
        lastElement.click()

        time.sleep(1)

        # 用pushplus公众号向微信推送消息,提示每次签到成功。(预防某天签到失败还能有手动再签的机会)
        content = person[0] + \'每日填报成功\'
        send_message_url = \'http://www.pushplus.plus/send?token=\' + person[5] + \'&content=\' + content
        requests.get(url=send_message_url)
    finally:
        driver.quit()


if __name__ == \'__main__\':
    persons = [
        [\'(姓名)\', \'(学号)\', \'福建省\', \'福州市\', \'鼓楼区\', \'(pushplus的token)\']
    ]
    for p in persons:
        print(p)
        automatic(p)