Huajiの小窝.

研讨室预约填写信息自动化工具

2024/11/27
loading

研讨室预约填写信息自动化工具

由于填写研讨室预约信息过程繁琐,开发了一个自动化工具来节省时间,基于 Python 和任务调度框架实现。

注意:本工具仅供学习和个人使用,请勿用于商业用途。

实现思路

1.使用 selenium 模拟表单提交,自动化处理输入信息,搭配定时任务实现全流程自动化。

2.使用JavaScript在当前预约界面执行输入。

背景来源

最近发现研讨室预约系统繁琐,填写时间、用途等信息需要耗费很多精力,因此萌生了通过脚本实现简化流程的想法。

具体操作步骤

  1. 分析预约系统接口

    • 使用浏览器开发者工具(F12)捕获预约系统的网络请求,定位提交信息的接口。
    • 获取所需的表单字段,如姓名、用途、时间等。
  2. 编写自动化脚本

    • 使用 selenium库模拟浏览器操作,提交预约信息。
    • 将参数动态化,便于后续修改和扩展。
  3. 环境配置

    • 安装必要的依赖库:pip install selenium
    • 部署脚本到支持定时任务的平台(如 crontab、青龙面板)。

示例代码

下述代码只有填写信息功能,没有选择预约时间的操作

以下是selenium核心实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from selenium import webdriver
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

gecko_path = 'geckodriver.exe'
ac = '2**********'
pwd = '******'
participants = [
['张三', '2402000****', '13888888888'],
['李四', '2402000****', '13888888888'],
['王五', '2402000****', '13888888888']
]

# 设置Firefox选项
firefox_options = Options()
service = FirefoxService(executable_path=gecko_path)
# 初始化WebDriver
driver = webdriver.Firefox(service=service, options=firefox_options)
driver.get('http://library.ouc.edu.cn/html/SeminarRoom/Login')

# 等待页面加载完成,可以通过等待某个元素出现来确认
try:
# 登录
account = driver.find_element(By.XPATH, '/html/body/div[2]/div/div[2]/div/form/div[1]/input')
password = driver.find_element(By.XPATH, '//*[@id="PassWord"]')
account.send_keys(ac)
time.sleep(2)
password.send_keys(pwd)
button = driver.find_element(By.XPATH, '/html/body/div[2]/div/div[2]/div/form/button')
button.click()
time.sleep(2)
read_button = driver.find_element(By.XPATH, '/html/body/div[1]/div[12]/div/div/div[3]/button')
read_button.click()

AAA = '/html/body/div/div[1]/div[2]/div[1]/div[2]/div[2]/form/div/div'

# 填写表单
phone = driver.find_element(By.XPATH, '//*[@id="phone"]')
phone.send_keys('13888888888')
reason = driver.find_element(By.XPATH, f'{AAA}[3]/div/textarea')
reason.send_keys('小组讨论')
seminar1 = driver.find_element(By.XPATH, '//*[@id="room3"]')#这里是研讨室二
#room对应预约房间从左往右、从上往下的顺序(好像是)
seminar1.click()
time.sleep(0.1)


# 增加参与者
plus = driver.find_element(By.XPATH, f'{AAA}[6]/div/table/thead/tr/th[4]/a/i')
for _ in range(3):
plus.click()
time.sleep(0.1)

# 填写参与者信息
for index, (name, id_num, tel) in enumerate(participants):
name_elem = driver.find_element(By.XPATH, f'{AAA}[6]/div/table/tbody/tr[{index + 1}]/td[1]/p')
id_elem = driver.find_element(By.XPATH, f'{AAA}[6]/div/table/tbody/tr[{index + 1}]/td[2]/p')
tel_elem = driver.find_element(By.XPATH, f'{AAA}[6]/div/table/tbody/tr[{index + 1}]/td[3]/p')
name_elem.send_keys(name)
id_elem.send_keys(id_num)
tel_elem.send_keys(tel)
time.sleep(0.1)

finally:
# 关闭浏览器,因为还未提交,所以不关闭
# driver.quit()
pass

如果没有安装selenium,还可以用f12打开控制台执行js代码进行填写,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(async function () {
const participants = [
['张三', '2402000****', '13888888888'],
['李四', '2402000****', '13888888888'],
['王五', '2402000****', '13888888888']
];

try {
document.evaluate(
'/html/body/div[1]/div[12]/div/div/div[3]/button',
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue.click();

// 填写表单
const AAA = '/html/body/div/div[1]/div[2]/div[1]/div[2]/div[2]/form/div/div';

document.getElementById('phone').value = '13888888888';

document.evaluate(
`${AAA}[3]/div/textarea`,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue.value = '小组讨论';

document.getElementById('room2').click();

await new Promise(resolve => setTimeout(resolve, 100));

// 增加参与者
const plusButton = document.evaluate(
`${AAA}[6]/div/table/thead/tr/th[4]/a/i`,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
).singleNodeValue;

for (let i = 0; i < 3; i++) {
plusButton.click();
await new Promise(resolve => setTimeout(resolve, 100));
}

// 填写参与者信息
participants.forEach((participant, index) => {
const [name, idNum, tel] = participant;

const nameXPath = `${AAA}[6]/div/table/tbody/tr[${index + 1}]/td[1]/p`;
const idXPath = `${AAA}[6]/div/table/tbody/tr[${index + 1}]/td[2]/p`;
const telXPath = `${AAA}[6]/div/table/tbody/tr[${index + 1}]/td[3]/p`;

const nameNode = document.evaluate(nameXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const idNode = document.evaluate(idXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const telNode = document.evaluate(telXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

if (nameNode) nameNode.innerText = name;
if (idNode) idNode.innerText = idNum;
if (telNode) telNode.innerText = tel;
});
} catch (err) {
console.error('执行过程中出现错误:', err);
}
})();

CATALOG
  1. 1. 研讨室预约填写信息自动化工具
    1. 1.1. 实现思路
      1. 1.1.1. 背景来源
      2. 1.1.2. 具体操作步骤
      3. 1.1.3. 示例代码