1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/W6Zbs4若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/W6Zbs4
若失效,可用地址
https://www.aliyun.com/minisite/goods?source=5176.29345612&userCode=49hts92d
腾讯云:
https://curl.qcloud.com/wJpWmSfU
若失效,可用地址
https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=ad201ee2ef3b771157f72ee5464b1fea&from=console
华为云
https://activity.huaweicloud.com/cps.html?fromacct=64b5cf7cc11b4840bb4ed2ea0b2f4468&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905
2.部署教程
3.代码如下
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
import pdfplumber
import re
import os
from openai import OpenAI
# 全局变量
count = 0
# 读取键盘输入并赋值给interval
def get_user_input():
print("请选择模式:")
print("1. 测试")
print("2. 考试")
mode = int(input("请输入模式编号(1或2):"))
print("请输入做题间隔时间(单位为秒):")
interval = float(input())
print("请输入做题总数:")
total = int(input())
print(f"本次时间间隔为:{interval}s,预期答题时间:{interval * total + 60}s")
return mode, interval, total
# 设置DataBase
def extract_text_from_pdf(pdf_path, start_page, end_page):
text_list = []
with pdfplumber.open(pdf_path) as pdf:
for page_number, page in enumerate(pdf.pages, start=1):
if end_page is not None and page_number > end_page:
break
if page_number >= start_page:
text = page.extract_text()
if text:
text_list.append(text)
return text_list
def parse_text_to_dict(text_list):
word_dict = {}
pattern = re.compile(r'(\b\w+\b)\s+(.*)')
for text in text_list:
lines = text.splitlines()
for line in lines:
match = pattern.match(line)
if match:
word = match.group(1)
meaning = match.group(2).strip()
word_dict[word] = meaning
return word_dict
def parse_text_to_dict_NI(text_list):
word_dict = {}
pattern = re.compile(r'(\b\w+\b)\s+(.*)')
for text in text_list:
lines = text.splitlines()
for line in lines:
match = pattern.match(line)
if match:
meaning = match.group(2)
word = match.group(1).strip()
word_dict[word] = meaning
return word_dict
# 初始化浏览器
def init_browser():
mobile_emulation = {
"deviceMetrics": {
"width": 1707,
"height": 773,
"pixelRatio": 1.0
},
"userAgent": "Mozilla/5.0 (Linux; Android 13; IQOO 18) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36"
}
chrome_options = Options()
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
wd = webdriver.Chrome(service=Service(r"./chromedriver.exe"), options=chrome_options)
return wd
# 开始测试或考试
def start_test_or_exam(wd, interval, total, mode):
global count
for i in range(total):
question = WebDriverWait(wd, 15, 0.5).until(
lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[2]/div/div[1]/span[2]'))
question = question.text.split()[0].strip()
A = WebDriverWait(wd, 15, 0.1).until(lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[3]/div/div[1]/div[1]/span'))
B = WebDriverWait(wd, 15, 0.1).until(lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[3]/div/div[2]/div[1]/span'))
C = WebDriverWait(wd, 15, 0.1).until(lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[3]/div/div[3]/div[1]/span'))
D = WebDriverWait(wd, 15, 0.1).until(lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[3]/div/div[4]/div[1]/span'))
At = A.text.split('.')[1].strip()
Bt = B.text.split('.')[1].strip()
Ct = C.text.split('.')[1].strip()
Dt = D.text.split('.')[1].strip()
con = f"""{question}\nA.{At}\nB.{Bt}\nC.{Ct}\nD.{Dt}"""
print(con)
if question.isalpha():
flag = 1
for word, meaning in word_dict.items():
if question == word:
if At in meaning and Bt not in meaning and Ct not in meaning and Dt not in meaning:
flag = 0
A.click()
break
if Bt in meaning and At not in meaning and Ct not in meaning and Dt not in meaning:
flag = 0
B.click()
break
if Ct in meaning and Bt not in meaning and At not in meaning and Dt not in meaning:
flag = 0
C.click()
break
if Dt in meaning and Bt not in meaning and Ct not in meaning and At not in meaning:
flag = 0
D.click()
break
if flag:
count += 1
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
completion = client.chat.completions.create(
model="deepseek-chat",
messages=[
{'role': 'system', 'content': '你要做的是词义匹配,找到和英文单词最贴切的中文解释,最终回答一个用"-"包起来的大写字母作为答案,例如"-B-"'},
{'role': 'user', 'content': con},
]
)
WebDriverWait(wd, 10, 0.1).until(lambda wd: '-' in completion.choices[0].message.content)
print(f"-----(英译中){i + 1} " + completion.choices[0].message.content)
if '-A-' in completion.choices[0].message.content:
A.click()
if '-B-' in completion.choices[0].message.content:
B.click()
if '-C-' in completion.choices[0].message.content:
C.click()
if '-D-' in completion.choices[0].message.content:
D.click()
completion.choices[0].message.content = None
else:
flag = 1
for word, meaning in word_dict_NI.items():
if question in word:
if At in meaning:
flag = 0
A.click()
break
if Bt in meaning:
flag = 0
B.click()
break
if Ct in meaning:
flag = 0
C.click()
break
if Dt in meaning:
flag = 0
D.click()
break
if flag:
count += 1
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
completion = client.chat.completions.create(
model="deepseek-chat",
messages=[
{'role': 'system', 'content': '你要做的是词义匹配,找到和中文意思最贴切的英语单词,最终回答一个用"-"包起来的大写字母作为答案,例如"-B-"'},
{'role': 'user', 'content': con},
]
)
WebDriverWait(wd, 10, 0.1).until(lambda wd: '-' in completion.choices[0].message.content)
print(f"-----(中译英){i + 1} " + completion.choices[0].message.content)
if '-A-' in completion.choices[0].message.content:
A.click()
if '-B-' in completion.choices[0].message.content:
B.click()
if '-C-' in completion.choices[0].message.content:
C.click()
if '-D-' in completion.choices[0].message.content:
D.click()
completion.choices[0].message.content = None
time.sleep(interval)
time.sleep(0.1)
if mode == 2: # 如果是考试模式,提交答案
wd.find_element(By.XPATH, '//*[@id="app"]/div/div[2]/div/div/div[3]/span').click()
time.sleep(0.1)
wd.find_element(By.XPATH, '/html/body/div[4]/div[2]/button[2]').click()
print(f"使用了{count}次AI")
time.sleep(999999)
# 主函数
def main():
mode, interval, total = get_user_input()
print("Database Setting>>>.....")
pdf_path = r'./Data.pdf'
start_page = 1
end_page = 113
text_list = extract_text_from_pdf(pdf_path, start_page, end_page)
global word_dict, word_dict_NI
word_dict = parse_text_to_dict(text_list)
word_dict_NI = parse_text_to_dict_NI(text_list)
for word, meaning in word_dict.items():
print(f"{word}=={meaning}")
for word, meaning in word_dict_NI.items():
print(f"{word}=={meaning}")
print("Task Beginning>>>.....")
wd = init_browser()
wd.get("https://skl.hduhelp.com/?type=5#/english/list")
wd.maximize_window()
time.sleep(2.5)
began = WebDriverWait(wd, 150, 0.1).until(lambda wd: wd.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div/div[2]/div[2]/div/button'))
began.click()
start_test_or_exam(wd, interval, total, mode)
if __name__ == "__main__":
main()
解析
该脚本为我爱记歌词自动答题脚本,脚本主要作用:
通过 Selenium 打开指定网站的英语题库页面,自动开始做题(支持"测试/考试"两种模式)。
先从本地 PDF(Data.pdf) 提取"单词-释义"数据,建立词典用于本地匹配答案。
若本地词典无法唯一确定答案,则调用 DeepSeek Chat API(通过
openai
客户端、DEEPSEEK_API_KEY
环境变量)让模型判定并选项自动点击。根据设定的做题间隔与做题总数循环答题;考试模式结束后自动提交。
记录并输出本次使用 AI 判题的次数。
主要函数/方法作用
get_user_input()
交互式读取模式(1测试/2考试)、两题间隔秒数、总题数,并打印预计用时。extract_text_from_pdf(pdf_path, start_page, end_page)
用 pdfplumber 读取 PDF 指定页区间的文本,返回按页组成的文本列表。parse_text_to_dict(text_list)
将 PDF 文本解析为英→中词典:以每行"英文 单行中文释义"格式,构建{英文: 中文释义}
。parse_text_to_dict_NI(text_list)
与上类似,但用于中→英方向匹配:构建{英文: 中文释义}
,供中文题干反查英文选项。init_browser()
配置移动端 UA 与分辨率,启动chromedriver.exe
并返回webdriver.Chrome
实例。start_test_or_exam(wd, interval, total, mode)
核心答题循环:抓取题干与 A/B/C/D 选项;
若题干为纯字母(英译中),用
word_dict
进行本地匹配;无法唯一确定时调用 DeepSeek 让模型返回-A-/ -B- / -C- / -D-
,再自动点击;否则视为中文题干(中译英),在
word_dict_NI
中查找包含关系;不确定时同样调用 DeepSeek 判定;每题间
time.sleep(interval)
;若模式为考试(
mode==2
),结束后自动点击交卷;打印本次使用 AI 的次数。
main()
调用get_user_input()
读取参数 → 解析 PDF 生成两套词典 → 启动浏览器 → 打开目标页面并点击"开始" → 调用start_test_or_exam()
执行全流程。
备注:脚本依赖
selenium
,pdfplumber
,openai
(DeepSeek 兼容接口),chromedriver.exe
。需要在环境中设置DEEPSEEK_API_KEY
;并确保Data.pdf
存在且页码范围正确。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
没有评论:
发表评论