抢场脚本配置记录

为了解决羽毛球场难抢,并且要七点早起的问题,我利用 python + selenium 写了一个抢场脚本,并利用 Linux crontab 实现定时运行的功能。脚本代码

Selenium


Selenium 是一个 web 自动化工具。

选择 Selenium 的原因

  • 上手简单,自动操作流程和人工操作一样
  • 体育场馆预约需要通过滑动验证码,selenium 能很方便地模拟鼠标运动

Selenium 基本操作

以下列出 selenium 可以实现并且在此脚本中使用的操作,具体的使用方法请自行搜索,这里不进行详细介绍。

浏览器

selenium 可以使用 Edge/Chrome/Firefox 等浏览器,使用 selenium 前需要确保安装浏览器驱动。在一些设备上很多浏览器可能无法使用,推荐使用 Chromium 代替 Chrome,提供一个下载链接 https://blog.csdn.net/xxxlu_top/article/details/112548849,可以在其中找到系统对应的驱动版本。在我们的方案中,使用树莓派运行脚本,树莓派的架构是 arm64。

新版 selenium 使用 Service 添加驱动路径。

打开浏览器可以使用 Options 类进行设置。 --headless 比较常用,表示无界面形态,用于直接命令行执行脚本。--window-size=4000,1600 可以使浏览器放大,如果不进行放大,会出现鼠标无法拖拽放置等问题;推测原因可能是需要拖放的内容在屏幕外,无法进行操作。

查找元素: find_element

注意在新版 selenium 下 find_element_by_xxx 一类函数已被弃用,一律使用 find_element(By.xxx, 'str')

同时,如果需要查找邻节点,如父节点、子节点、兄弟节点,可以使用 xpath 进行查找。

切换: switch_to

可以切换到别的 iframe(switch_to.frame),浏览器弹窗(switch_to.alert)。

填入内容: send_keys

可以传入字符、键盘输入、鼠标输入。

鼠标操作

在找到元素之后,可以对元素进行点击(click),拖拽放置(drag_and_drop)等动作。如果需要自行定义一系列动作,可以使用 ActionChains 类。

执行语句: execute_script

如执行 JavaScript 语句 execute_script("javascript:some js")

条件 expected_conditions EC

可以检测元素的状态,如是否可点击(EC.element_to_be_clickable),是否过期(EC.staleness_of)

常见用于显式等待中。

等待

分为显式等待和隐式等待。

  • 显式等待 WebDriverWait(driver, time).until(EC) 一直等待 time 长的时间直到 EC 里的条件满足
  • 隐式等待 implicit_wait(time) 一直等待 time 长的时间

Crontab


Linux 的 crontab 命令用于循环执行定时任务。

首先确保开启 crond 服务。

命令 crontab -e 打开 crontab 文件,首次打开会选择编辑器,建议使用 vim。如果之后想用别的编辑器打开,可以先输入 export EDITOR=xxx

crontab 文件格式如下:

* * * * * 执行的任务

前面 * 的位置代表时间,根据自己的需求进行修改。

执行的任务中全都需要使用完整的路径,当然也可以自己修改 PATH。

其他


网页中的图片地址是 data:image/…

很多图片使用 data URI scheme 直接嵌入到网页中,格式如上文所示。提供一段解码代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def decode_image(src):
# 1、信息提取
result = re.search("data:image/(?P<ext>.*?);base64,(?P<data>.*)", src, re.DOTALL)
if result:
ext = result.groupdict().get("ext")
data = result.groupdict().get("data")

else:
raise Exception("Do not parse!")

# 2、base64解码
img = base64.urlsafe_b64decode(data)

# 3、二进制文件保存
filename = "{}.{}".format(uuid.uuid4(), ext)
with open(filename, "wb") as f:
f.write(img)

return filename

通过滑动验证码

通过滑动验证码的关键是识别出缺失部分的位置。在脚本中采用的方法是,先对图片进行边缘检测,再提取轮廓,使用矩形框标出轮廓,最后根据框的大小跟缺失部分的大小进行比较,得到缺失部分的位置。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!