文章目录
基于对学校打卡页面的简单研究,啊,使用Python和Selenium做了一个打卡程序。加上Windows系统自带的计划任务功能,可以轻松实现每天定时自动打卡。从此再也不用被催被训。
这肯定不用多说了。吧。
浏览器使用火狐的长期支持版本,即Firefox LTS。在官网的“更多语言与下载”页面下拉到底就可以看见。

谷歌浏览器不太好使,更新太多,后续写代码时也有一种怪怪的感觉。但是完全可以实现一样的功能哈。只能说是个人喜好问题选择了火狐长期支持版。
然后下载浏览器驱动。这个驱动是自动控制时要用的。火狐浏览器需要用geckdriver,下载地址在https://github.com/mozilla/geckodriver/releases。谷歌浏览器用chromedriver。
这玩意下载来了之后是要在Windows环境变量里添加参数才能使用的。但是我懒得再加了。由于Python在部署的过程中已经把Python自己的文件夹添加到了环境变量里,所以直接把drive扔进Python根目录里就行了。万岁。
按常规方法装就行,没有什么特别的,也没有什么要改的地方。
pip install selenium
先加上必须用到的time和random基础库。再把Selenium里要用的部分统统import。
import time
import random
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
用Python,你的代码可以写得很诡异,但是不可以不规整。记住,在Python里,书写规范是最重要的一环,甚于效率。所以我们定义一个构造方法先。
class Auto_punch:
def __init__(self):
self.option = None
self.options = None
self.driver = None
self.vars = None
没什么特别的用处,就是符合完整的结构书写规范。
先得打开浏览器。这个部分还包括对浏览器进行一些初始设置。
def setup(self):
options = webdriver.FirefoxOptions()
options.set_preference("general.useragent.override",
'-user-agent="Mozilla/5.0 (Linux; U; '
'Android............Gecko) Version/4.0 '
'Chrome/78.0.3904.108 Quark/5.5.5.204 Mobile '
'Safari/537.36"')
options.set_preference("geo.prompt.testing", True)
options.set_preference("geo.prompt.testing.allow", True)
# self.options.add_argument('--disable=gpu')
self.driver = webdriver.Firefox(options=options)
self.driver.implicitly_wait(20)
self.vars = {}
选用火狐浏览器有这一个好:火狐浏览器的设置是一种表单格式。比较直观,也比较详细。
首先是伪装成手机的header。这里把useragent设成了一串相当抽象的字符串。你不理解没关系,浏览器理解就够了。
options.set_preference("general.useragent.override",
'-user-agent="Mozilla/5.0 (Linux; U; '
'Android............Gecko) Version/4.0 '
'Chrome/78.0.3904.108 Quark/5.5.5.204 Mobile '
'Safari/537.36"')
然后是值得注意的两行代码,也算是本环节的关键:
options.set_preference("geo.prompt.testing", True)
options.set_preference("geo.prompt.testing.allow", True)
这两行的作用就是,当浏览器弹出“网页请求获取地理位置数据”窗口时,自动点确定。
打卡网页没有获取到位置数据的话是不准打卡的。既然是数据,那就是可以改的。详见下文…
self.options.add_argument('--disable=gpu')
这个是比较常规的一个选项,不显示窗口,后台自动运行。由于不利于观察运行调试,就注释掉了这行。如果是打算挂在服务器上使用,可以取消注释。
self.driver = webdriver.Firefox(options=options)
self.driver.implicitly_wait(20)
这个是网页加载等待时间。如果需要操作的某个网页元素迟迟没有加载出来,那么它最多会额外等待20秒。这个不影响程序运行速度,所以填大一点也没什么影响。
def quit(self):
self.driver.quit()
def open_url(self):
self.driver.get(
"https://wb.ndky.edu.cn/mobile/index.html?useragent=wxwork&code"
"=zReBN0F8yFPe6RQ2JaevkmPiYCGnTAGb5cnWSsM0k1Q&state=STATE")
self.driver.set_window_size(480, 800)
这两个函数就很直白了,分别负责完成任务后退出浏览器和操控浏览器打开打卡页面并设定浏览器窗口大小。
重头戏。本项目最核心的部分,利用Selenium强大无比的仿真控制功能完成网页定位与打卡。
def Auto_Punch(self):
self.driver.find_element(By.NAME, "username").click()
self.driver.find_element(By.NAME, "username").send_keys("114514")
self.driver.find_element(By.NAME, "password").click()
self.driver.find_element(By.NAME, "password").send_keys("1919810")
self.driver.find_element(By.CSS_SELECTOR, ".weui-btn").click()
self.driver.find_element(By.CSS_SELECTOR, ".hot-service-list .grid-item-wrapper:nth-child(1)").click()
self.driver.execute_script("navigator.geolocation.getCurrentPosition = function(success) { success({coords: {"
"latitude: 30.198982, longitude: 121.298721}}); }")
self.driver.execute_script("arguments[0].click()",self.driver.find_element(By.CSS_SELECTOR, ".weui-cell:nth"
"-child(72) > "
".weui-cell__bd"))
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR, ".weui-cell:nth-child(72) > .weui-cell__bd").click()
self.driver.find_element(By.CSS_SELECTOR, ".weui-check__label:nth-child(2)").click()
self.driver.find_element(By.CSS_SELECTOR, ".weui-btn").click()
time.sleep(10)
element = self.driver.find_element(By.CSS_SELECTOR, ".weui-btn")
actions = ActionChains(self.driver)
actions.move_to_element(element).perform()
self.driver.find_element(By.CSS_SELECTOR, ".to-lobby").click()
self.driver.find_element(By.CSS_SELECTOR, ".weui-tabbar__item:nth-child(2) > .weui-tabbar__label").click()
self.driver.find_element(By.CSS_SELECTOR, ".weui-btn").click()
element = self.driver.find_element(By.CSS_SELECTOR, ".weui-btn")
actions = ActionChains(self.driver)
actions.move_to_element(element).perform()
self.driver.find_element(By.LINK_TEXT, "确认").click()
self.driver.find_element(By.NAME, "username")利用名称来匹配元素。这里直接找到用户名输入框,然后通过.click()和.send_keys()函数点击输入框并输入用户名。下同。
self.driver.find_element(By.CSS_SELECTOR, ".weui-btn")利用css的class属性值匹配元素。这是Selenium官方强推的匹配方法,又快又精简。
self.driver.execute_script("navigator.geolocation.getCurrentPosition = function(success) { success({coords: {"
"latitude: 30.198982, longitude: 121.298721}}); }")
这段是之前关于打卡网页定位方式研究的成果。通过Selenium直接给负责定位的Javascript发一个fake callback。效果拔群。这个方法理论上可以解决所有网页定位问题。
time.sleep(1)负责在无法精确得知等待时间时强制等待一个较长的固定时间。比较常用。据说Selenium老手就很少用这个了。
最后构建main函数。
if __name__ == '__main__':
delay = random.randint(0, 600)
print("本次随机延迟为:" + str(delay))
time.sleep(delay)
print("缓冲结束")
run = Auto_punch()
run.setup()
print("初始化完成")
run.open_url()
print("打开打卡页面")
print("开始自动打卡")
run.Auto_Punch()
print("打卡完成")
print("关闭程序")
run.quit()
为避免后台检测数据异常,这里还使用了一个简单的随机延迟函数,使得每天的自动打卡时间点都不一样,即delay = random.randint(0, 600) time.sleep(delay)。
由于windows计划任务配置python脚本的流程过于麻烦,容易出差错,所以我们直接把这个脚本打包成一个exe程序。
pip install pyinstaller安装打包库。
shift+鼠标右键点击刚写好的python程序的文件夹,在弹出的选项中点击"在此处打开命令行窗口"或者“在此处打开PowerShell窗口”。
pyinstaller -F 自动打卡.py打包程序。

然后在输出的dist文件夹里就可以看见打包好的exe程序了。
这个太简单了就不写了,随便百度一下再按照自己的需求做修改就行。开摆!
一定要经过复数次的手动测试才可以正式投入使用。血的教训。这个不会出问题的最终版本建立在翻车无数次的基础上…

python+selenium简单易上手,更多资料敬请百度。。。我自动打卡无罪,毕竟我原本就是自动化学生,,,
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.