学校用来预约场地的服务器实在承载能力有限。八点钟登上去,起码要八点零五才能第一次刷新成功,加上一般就开放五六片场地,根本不可能抢不到
那么,就只能用科技对付科技了,也好让我早上多睡会好歹脚本抢不到没有拼手速被服务器gank那么气
一、安装Chrome
先将Chrome RPM包下载下来
wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
安装两个依赖包
yum install -y lsb
yum install -y libXScrnSaver
从已下载到本地的RPM包安装Chrome
yum localinstall -y google-chrome-stable_current_x86_64.rpm
2022年六月,安装的版本是102.0.5005.61
二、安装chromedriver
从淘宝镜像库找对应Chrome版本的驱动 http://npm.taobao.org/mirrors/chromedriver/
wget https://registry.npmmirror.com/-/binary/chromedriver/102.0.5005.61/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/bin/
chromedriver --version
只提供了zip包,如果系统没有装unzip zip的话一并装了就行了yum install -y unzip zip
最后通过chromedriver --version验证安装版本
三、安装Python3
Centos7本身是有Python2.7的,但是因为yum依赖于Python2.7,直接卸载旧版本换新的会有很多问题所以还是比较建议装新版本时候软链接用/usr/bin/python3而不是直接写python,毕竟python本身就存在2和3不兼容问题,好区分一点
- 
安装依赖
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc* make -y - 
下载安装包
wget https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tar.xz - 
解压
tar -Jxvf Python-3.8.10.tar.xz - 
配置安装路径
cd Python-3.8.10 ./configure prefix=/usr/local/python3 - 
编译安装
make && make install - 
配置软连接
ln -s /usr/local/python3/bin/python3 /usr/bin/python3 ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3 - 
安装pip
wget py # 下载 python3 get-pip.py # 安装 pip -V 
用pip3在linux上一个个添依赖是比较麻烦的事情,如果在Windows上有比较完整的依赖,可以直接dump一个依赖列表到服务器上,让pip自动添加
#	在Windows上CMD
cd Desktop
pip freeze > packages.txt
如果Python版本不同强烈不建议这么搞,很容易发生版本对不上问题
然后到Centos上进行pip3
pip3 install -r packages.txt
当然如果只需要Selenium,直接装就行了
pip3 install selenium
四、chrome_options
使用selenium调用chromedriver也并不顺利,以下是Centos7配合上述Chrome版本,实际可用的一套设置
chrome_options = Options()
chrome_options.add_argument('--headless')  # 无界面
chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在报错问题
chrome_options.add_argument('--disable-gpu')   # 禁用GPU硬件加速。如果软件渲染器没有就位,则GPU进程将不会启动。
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
五、定时任务
因为是一个预约球场的脚本,每天系统开放时间是早上八点,那么我们用定时任务让脚本在七点五十九跑起来Centos7下默认安装有crontab,如果没有也可以直接yum yum install crontabs
crontab -e		# 编辑定时任务,会以vim的形式编辑
# 在文档里加一条定时任务,每天的7点59分执行,注意用绝对路径
59 7 * * * /usr/bin/python3 /usr/local/reserve/reserve.py
接下来重启一下crontab服务
service crond restart
再查看一下当前系统的定时任务列表
crontab -l
没有问题的话,就大功告成了
六、顺便贴一下脚本代码
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import datetime
import ddddocr
import sys
class Logger(object):
    def __init__(self, filename='default.log', stream=sys.stdout):
        self.terminal = stream
        self.log = open(filename, 'a')
    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)
    def flush(self):
        pass
myheaders = {
    "Accept": "text/plain, */*; q=0.01",
    "Accept-Encoding": "br, gzip, deflate",
    "Accept-Language": "zh-cn",
    "Host": "yuyue.seu.edu.cn",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"
}
myurl = "http://yuyue.seu.edu.cn/eduplus/order/order/order/judgeUseUser.do?sclId=1"
logfile = 'default.log'
def wait_element_click(driver, wait, path):
    wait.until(EC.element_to_be_clickable((By.XPATH, path)))
    driver.find_element_by_xpath(path).click()
def request_check_code(r):
    ocr = ddddocr.DdddOcr(show_ad=False)
    return ocr.classification(r.content)
def login(uid, pwd):
    # chromedriver_autoinstaller.install()
    chrome_options = webdriver.ChromeOptions()
    # 指定chrome启动类型为headless 并且禁用gpu
    chrome_options.add_argument('--headless')  # 无界面
    chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在报错问题
    chrome_options.add_argument('--disable-gpu')   # 禁用GPU硬件加速。如果软件渲染器没有就位,则GPU进程将不会启动。
    chrome_options.add_argument('--disable-dev-shm-usage')
    driver = webdriver.Chrome(options=chrome_options)
    driver.get("http://yuyue.seu.edu.cn/eduplus/order/initOrderIndex.do?sclId=1")
    driver.find_element_by_xpath("//div[@class='auth_tab_content']/div[1]/form/p[1]/input").send_keys(uid)
    driver.find_element_by_xpath("//div[@class='auth_tab_content']/div[1]/form/p[2]/input").send_keys(pwd)
    driver.find_element_by_xpath("//div[@class='auth_tab_content']/div[1]/form/p[5]/button").click()
    wait = WebDriverWait(driver, 2, 0.5)
    try:
        alert = driver.switch_to.alert  # 切换到弹窗
        # print("alert: " + alert.text)  # 打印弹窗显示的信息:Alert Message
        alert.accept()
    except:
        # print("no alert")
        pass
    driver_cookies = driver.get_cookies()
    c = {c['name']: c['value'] for c in driver_cookies}
    driver.close()
    return c
def reserve(user):
    uid = user["uid"]
    pwd = user["pwd"]
    target_time = user["target_time"]
    target_weight = user["target_weight"]
    name = user["name"]
    phone = user["phone"]
    c = login(uid, pwd)
    # r=requests.post(url,headers=myheaders,params=payload,cookies=c)
    image_url = "http://yuyue.seu.edu.cn/eduplus/validateimage"
    r = requests.get(image_url, headers=myheaders, cookies=c)
    vc = ""
    vc = request_check_code(r)
    print(vc)
    url_judge = "http://yuyue.seu.edu.cn/eduplus/order/order/order/judgeUseUser.do?sclId=1"
    """itemId
        羽毛球 10
        乒乓球 7
    """
    payload_judges = []
    date_time = (datetime.date.today() + datetime.timedelta(days=2)).strftime("%Y-%m-%d")
    for time, weight in zip(target_time, target_weight):
        order_time = date_time + " " + time
        print(order_time + " " + name)
        payload_judge = {"ids": "", "useTime": order_time, "phone": phone, "remark": "", "itemId": "10",
                         "allowHalf": "2",
                         "validateCode": vc}
        for i in range(int(10 * weight + 0.5)):
            payload_judges.append(payload_judge)
    """ First Touch
    """
    try:
        r = requests.post(url_judge, params=payload_judges[0], headers=myheaders, cookies=c)
    except:
        pass
    print(r.text)
    while r.text.find("code") >= 0:
        print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '' + "get new code------------")
        r = requests.get(image_url, headers=myheaders, cookies=c)
        vc = request_check_code(r)
        payload_judges[0]["validateCode"] = vc
        r = requests.post(url_judge, params=payload_judges[0], headers=myheaders, cookies=c)
        print(vc)
    i = 0
    print('\n' + r.text)
    current_target = payload_judges[0]["useTime"]
    """ Repeat
    """
    while r.text.find("error") >= 0 and i < 200:
        for payload_judge in payload_judges:
            if payload_judge["useTime"] == current_target:
                payload_judge["validateCode"] = vc
            else:
                r = requests.get(image_url, headers=myheaders, cookies=c)
                payload_judge["validateCode"] = request_check_code(r)
            r = requests.post(url_judge, params=payload_judge, headers=myheaders, cookies=c)
            print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '' + payload_judge["useTime"] + ' ' + r.text)
            while r.text.find("code") >= 0:
                print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '' + "get new code------------")
                r = requests.get(image_url, headers=myheaders, cookies=c)
                vc = request_check_code(r)
                payload_judge["validateCode"] = vc
                r = requests.post(url_judge, params=payload_judge, headers=myheaders, cookies=c)
                print(vc)
        i = i + 1
    if i == 200:
        print(name + "failed" + "  i=" + str(i))
    else:
        print(name + "success" + "  i=" + str(i))
if __name__ == "__main__":
    sys.stdout = Logger(logfile, sys.stdout)
    sys.stderr = Logger(logfile, sys.stderr)  # redirect std err, if necessary
    user = {
        "uid": "#{一卡通号}",
        "pwd": "#{一卡通号}",
      	# 因为每天开放时间段都不一样,可以定几个时间按请求比例抢
        "target_time": ("16:00-17:00", "15:00-16:00", "17:00-18:00", "18:00-19:00", "19:00-20:00"),
        "target_weight": (0.5, 0.15, 0.15, 0.1, 0.1),
        "name": "#{姓名,写啥都行}",
        "phone": "#{手机号,也是写啥都行}"
    }
    reserve(user)
- 稍微优化了一下,可以几个时间段一起抢
 - 输出日志,没抢到可以看到原因
 
第二天早上起来一看
YES!
好吧,其实这是一周里唯一一次成功抢到的,靠的还是学校大发慈悲放了四片场地