需求
最近突然有朋友对投票刷票有需求,正好自己空了下来,就帮他写了个简单的多线程投票脚本。因为不想考虑过多的session、cookie以及post data,所以直接使用了自动化工具Selenium
简单地说,Selenium就是一个通过执行预先设置的Browser的指令,解放双手,提高工作效率。
不同于通用的流行python网络模块,Selenium更像是市面上流行的按键精灵类似的软件,通过设定特定的工作流程,保证任务的完成。任务的实际执行者是Browser本身。
Selenium对网页的request、response、解析等操作都是另外的伪浏览器进程执行,然后将获取的数据返回。而传统的python网络模块则通过python进程,对网页请求、回应。显然网络模块会更加高效,而对于普通人,Selenium的操作更加直观。
1 |
|
分析
如上代码所示,在本次投票中,所有的候选人名单都包含在checkbox
。我们首先在Selenium中使用Browser Driver定位到需要选中的某个或某几个checkbox
,然后将这些checkbox
选中。
与以前不同的是,投票网页的checkbox
的input
标签中,id
、name
属性都是完全一致的。所以无法通过简单的ById
或ByName
直接定位。
之后通过绝对地址的次序依次抽丝剥茧获取Xpath,调试出错,不知道什么问题>GG<。然后就发现了input标签中的value
属性每个值都不一样。
例如获取第10个input元素的Xpath//input[@value="195"]
剩下的问题就水到渠成了。放上代码:
实现
Selenium实现
1 | from selenium import webdriver |
多线程
套上多线程模板:
1 | import threading |
requests
使用Selenium的效率实在不敢恭维,如果再加上多线程限制,在虚拟机中开大数目的伪浏览器资源,程序很容易崩溃。所以通过抓包之后改成了使用requests模块直接传递数据。
requests.Session()
类中自动维持cookies、headers、keep-alive等机制,但是在本次测试中,直接使用都无法达到效果,最后发现在初次get页面时,requests.Session不能直接获取维护cookies。所以改成自己封装cookies。代码如下:
1 | session=requests.Session() |