成熟的孩子要自己找题做——获取CSCore白金版
这是一篇针对CSCore的Selenium学习
历史背景
在北航,有这样一群人,他享有着别人所羡慕不来的东西——白金版CSCore,他可以查看自己的统计图,看到自己学习的时长与成果;他可以被计组邮箱推题,评测别人看不到的题。
我们至今未能得知白金版CSCore的来源,或许正如助教所说,这是未开发功能,只供部分人试用,又或许这是来自计组平台对于不好好做Pre的小可爱的一种Push,我们不得而知。
笔者很不幸运,便是普通版的一员,即使拿到了统计图的网址,点进去也会被骗到BiliBili的《never gonna give you up》。
然而我们是成年人了,要学会自己去获取资源,要有自己去拿到王者版CSCore的决心与努力,因此,我们就要学习WEB自动化工具——Selenium
当然,不学习也可以,它毕竟只是一个自动化软件,选择用勤劳的双手创造财富也可以,再不济,笔者也为大家提供了亡灵版CSCore,点击直接使用即可~
Selenium安装
Selenium是Python的一个工具包,所以我们需要先有Python,这里笔者推荐在安装解释器时直接使用Anaconda,其为Python的集成包,集成了Python及Python主流的工具包(库)多达1500个,让你可以开始你的Python编程。
如果你安装了Anaconda,那么大概率Anaconda中是有Selenium的,直接使用即可。
如果你只是安装了Python,那么大概率你是没有Selenium的,这时候需要在控制台输入以下指令:
1 | pip install selenium |
如果报错,请检查Python安装的正确性。
浏览器驱动安装
既然Selenium是WEB自动化工具,那么我们自然需要给浏览器安装驱动程序让Python可以驱动浏览器干活,这里针对不同的浏览器我们要安装不同的驱动,针对不同的浏览器版本也要选择安装不同的版本。
Firefox浏览器驱动:geckodriver
Chrome浏览器驱动:chromedriver
Edge浏览器驱动:MicrosoftWebDriver
拿Microsoft Edge举例,点击设置中的关于Microsoft Edge,我们可以看到Microsoft Edge的版本号:
发现开头的是108,所以我们去官网选择开头为108的驱动进行下载,后面不一样问题不大。
正式编写针对于CSCore的代码
CSCore网址分析
以上面的那道题为例,我们贴出网址如下:1
http://cscore.buaa.edu.cn/#/problem?ProblemId=336&PieId=896
分析看出,如果用小区做例子的话,PieId就是居民楼,ProblemId就是每一住户,我们遍历搜索每一居民楼,每一住户,问问家里是否有人(题目),便可以得到所有的隐藏题目,直升王者版CSCore,问题来了:
0.Selenium让我望而却步,我不能接受。
1.手动改网址需要1000x1000=10^6次,我们不能接受。
2.肉眼观察每一户是否有人住(有题),我们不能接受。
针对CSCore编写Selenium
Solution Zero
万事开头难,其实Selenium归根结底只是Python的一个库函数,学会则极其简单。
我们首先进行初步的设置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16edge_options = Options()
edge_options.add_argument('--headless') # 使用无头模式
edge_options.add_argument('--disable-gpu') # 禁用GPU,防止无头模式出现莫名的BUG
edge_options.add_argument('window-size=1920x1080') #设置为电脑显示分辨率大小
edge_options.add_argument('--start-maximized') #全屏展开浏览器
#以上都是对于Edge的设置,若用其他浏览器同理。
# 开启开发者模式
edge_options.add_experimental_option('excludeSwitches', ['enable-automation'])
# 禁用启用Blink运行时的功能
edge_options.add_argument('--disable-blink-features=AutomationControlled')
# 打开Edge
f = open("exercise.txt", "w")
driver = webdriver.Edge(options=edge_options)
driver.maximize_window() # 窗口最大化
driver.implicitly_wait(10) # 隐式等待10s查询元素
#以上是操作Edge驱动的基本过程
强调: 无头模式运行时不会将浏览器显示出来,所以如果你想观看自动化过程,请注释掉使用无头模式这条语句。
Solution First
1 | for i in range(1000): |
看不懂没关系,我们慢慢解释:
第一行是for循环标准语句,我们需要敲响1000户的们,所以范围是1000.
第二行是定义了个变量用来存放网址,用于后面搜到题我们往文档里写入网址。
第三行是Selenium功能,利用驱动打开该网址,中间str(i)对应户,我们遍历查找896号居民楼。
第四行到第十二行是一个特判:第一次进入CSCore,我们自然会需要登陆,这时候利用Selenium功能,捕捉元素(find_element)捕捉到登陆框,利用Selenium功能(send_keys)将“xxx”自动输入进去。之后利用Selenium功能,模拟点击(click)点击登陆,进入计组平台。之后便是天高任鸟飞,海阔凭鱼跃了。
TIPS:Selenium有很多定位元素的方法:1
2
3
4
5
6
7
8find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
我们采用最简单准确度高的操作,Xpath定位,毕竟我们是来学计组的,够用就行。
Xpath定位法
打开浏览器,F12进入开发者模式,出现如图所示画面,选择元素。
之后我们将鼠标移到每一行上面,会发现该行元素作用的范围将会以蓝色显示出来。
如图,右侧浅蓝色为我鼠标停留位置,左侧为定位到的元素,我们以CSCore的密码为例。
之后我们点击右键,按照下图所示复制出完整的XPath路径,一定要完整!否则定位大概率失效!
Solution Second
之后我们解决第二个问题:自动判断,那么我们如何才能实现自动判断?道理也很简单,我们只需要找出没有搜到题和搜到题的不同点即可,搜到题,会出现题目,没有搜到题,则是空白界面,所以我们只需要定位一个题目任意的元素,每次判断该元素是否出现,即可实现这个功能,代码如下:1
2
3
4
5
6
7
8try:
info = driver.find_element(By.XPATH, '/html/body/div/div[1]/div[1]/div/main/div/div/div/div[1]/h2').text
except:
None
else:
if info:
f.write(web) #找到就将Web里的网址写入文件中
f.write("\n") #换行
TIPS:
如果我们只想搜编程题,则考虑搜索编程题特有的提交题目那个框。
如果我们全都要,那么考虑搜索题目这个元素即可。
结语
至此,我们完成了Selenium针对计组的学习,之后我们想实现其他的功能按照上面类似操作即可,不记得对应的语句就去百度一下。
如果你真的这样做了,那么恭喜你的P0-P2将一帆风顺,因为你做到了许许多多的往年考题,还有自动评测。
恭喜获得王者版CSCore
完整源代码放送
1 |
|