缘起

这个故事起源于女票是一个bjd娃圈爱好者,我才知道在娃圈里经常通过微博私信的方式进行一些商品的交易,例如娃娃的面妆、衣服和娃娃本身,这就引发了抢票需求

流程:

在某一个整的时间点进行微信的私信发送,排名靠前者获得,人工操作反应慢,只能提前一秒卡点按发送,但是又有提前的风险(显示的发送时间未到整点时间会被淘汰),而且只能发送一条信息,发多了也会被淘汰

需求:

尽可能快的在某时间点反映并进行操作,并且不能早于该时间点进行操作,精准度要求高

分析了这个需求以后,立马想到用python进行自动化,计算机不仅操作速度比人快,而且不需要提前卡点操作,条件设置好不会导致过早发送

一、基本思路

因为只是微博私信发送,所以这个程序很简单,就是利用selenium打开微博网页,然后登陆,找到私信的用户,输入内容,点击发送,这都是selenium的常规操作,这里就不赘述了

程序的核心就是利用while循环判断时间,如果到了时间就点击发送

接下来主要讲:怎么卡点定时,和怎么提高运行效率

二、1.0版本:利用系统自带时间

while True:tt=time.asctime()if tt[14:16]=='00': #这里是一个简化处理,判断的时候直接用分钟数是否为“00”来代替整点,更严谨一点应该判断整个时间戳driver.find_element_by_xpath("//button[text()='发送']").click()breakelse:continue

最开始我想的很简单,就是获取系统自带的时间,但是运行过后发现电脑系统的时间和微博服务器的时间总有几秒的差距,因为微软和微博用的服务器不一样,所以总是有差距,对于卡点抢票的程序,这几秒的差距是致命的

为此我试过用time.sleep()强行把其中的差距补上,但是因为网速、时间运行差距累计的问题,这种方法显然是不可靠的,而且也失去了对时间精准度的核心需求,最后当然失败了,为此不得不接受女友的嘲笑(说还不如用手快……),因此必须获得微博服务器的时间

二、2.0版本:headers()获取微博服务器时间

因为我们用的是selenium,是一种完全模拟人操作浏览器的方法,而在微博的网页上又不会直接显示自己的服务器时间(只有每条微博的发布时间,而且有的只显示“刚刚”),甚至为此学习了手机自动化(因为手机上的时间和微博服务器的时间是一样的),但手机的运行效率太低,最终放弃了。

之后想到了用requests,因为requests中的headers()能够返回响应头,其中就包含了响应时间,而这个响应时间就来源于微博服务器的时间,即下图中的Date。

{'Server': 'WeiBo/LB', 'Date': 'Wed, 09 Mar 2022 08:09:05 GMT', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'Cache-Control': 'no-cache, must-revalidate', 'Expires': 'Sat, 26 Jul 1997 05:00:00 GMT', 'Pragma': 'no-cache, no-cache', 'DPOOL_HEADER': 'yf-pub-10-85-144-201', 'Content-Encoding': 'gzip'}

那么我们就可以在每次判断是否要发送前都用requests发起一次请求并获得响应时间,判断响应时间是否是我们预期的时间,然后点击发送。

while True:response = requests.get('https://weibo.com/')header = response.headers #返回的是一个字典if header['Date'][23:25] == '00' : #这里也是简化处理了driver.find_element_by_xpath("//button[text()='发送']").click()breakelse:continue

到这里基本可以了,但是在尝试了一次后以毫厘之差输给了别人,说明运行速度还是不够,于是思考如何提高运行效率。

三、3.0版本:requests.header()提高请求频率

在详细地了解requests.get()方法后,发现并没有能提高请求频率的参数,但是在requests库中还有另一个请求方法requests.head(),它的功能是以很少网络流量获取概要信息,看到这个功能介绍的时候感觉就很可能可以提高请求频率。于是我做了一个实验,在一秒内能请求并响应几次。

#get方法
tt_1 = time.time()
a=1
while True:tt_2 = time.time()if tt_2 - tt_1 <=1: #这是获取了时间戳(1970纪元后经过的浮点秒数),将两个时间戳相减不超过一秒作为测试的时间response = requests.get('https://weibo.com/')header = response.headersprint(header['Date'],a)a+=1 #次数else:break

这里尝试了好几次,基本上在15-18次左右

Mon, 07 Mar 2022 08:17:58 GMT 1
Mon, 07 Mar 2022 08:17:58 GMT 2
Mon, 07 Mar 2022 08:17:58 GMT 3
Mon, 07 Mar 2022 08:17:58 GMT 4
Mon, 07 Mar 2022 08:17:58 GMT 5
Mon, 07 Mar 2022 08:17:58 GMT 6
Mon, 07 Mar 2022 08:17:58 GMT 7
Mon, 07 Mar 2022 08:17:58 GMT 8
Mon, 07 Mar 2022 08:17:58 GMT 9
Mon, 07 Mar 2022 08:17:58 GMT 10
Mon, 07 Mar 2022 08:17:59 GMT 11
Mon, 07 Mar 2022 08:17:59 GMT 12
Mon, 07 Mar 2022 08:17:59 GMT 13
Mon, 07 Mar 2022 08:17:59 GMT 14
Mon, 07 Mar 2022 08:17:59 GMT 15
#head方法
tt_1 = time.time()
a=1
while True:tt_2 = time.time()response = requests.head('https://weibo.com/')header = response.headersif tt_2 - tt_1 <=1:print(header['Date'],a)a+=1else:break

测试后一秒内能进行30次左右

Mon, 07 Mar 2022 08:32:19 GMT 1
Mon, 07 Mar 2022 08:32:19 GMT 2
Mon, 07 Mar 2022 08:32:19 GMT 3
Mon, 07 Mar 2022 08:32:19 GMT 4
Mon, 07 Mar 2022 08:32:19 GMT 5
Mon, 07 Mar 2022 08:32:19 GMT 6
Mon, 07 Mar 2022 08:32:19 GMT 7
Mon, 07 Mar 2022 08:32:19 GMT 8
Mon, 07 Mar 2022 08:32:19 GMT 9
Mon, 07 Mar 2022 08:32:19 GMT 10
Mon, 07 Mar 2022 08:32:19 GMT 11
Mon, 07 Mar 2022 08:32:20 GMT 12
Mon, 07 Mar 2022 08:32:20 GMT 13
Mon, 07 Mar 2022 08:32:20 GMT 14
Mon, 07 Mar 2022 08:32:20 GMT 15
Mon, 07 Mar 2022 08:32:20 GMT 16
Mon, 07 Mar 2022 08:32:20 GMT 17
Mon, 07 Mar 2022 08:32:20 GMT 18
Mon, 07 Mar 2022 08:32:20 GMT 19
Mon, 07 Mar 2022 08:32:20 GMT 20
Mon, 07 Mar 2022 08:32:20 GMT 21
Mon, 07 Mar 2022 08:32:20 GMT 22
Mon, 07 Mar 2022 08:32:20 GMT 23
Mon, 07 Mar 2022 08:32:20 GMT 24
Mon, 07 Mar 2022 08:32:20 GMT 25
Mon, 07 Mar 2022 08:32:20 GMT 26
Mon, 07 Mar 2022 08:32:20 GMT 27
Mon, 07 Mar 2022 08:32:20 GMT 28
Mon, 07 Mar 2022 08:32:20 GMT 29
Mon, 07 Mar 2022 08:32:20 GMT 30
Mon, 07 Mar 2022 08:32:20 GMT 31
Mon, 07 Mar 2022 08:32:20 GMT 32

这是最新的优化方案了,还没来得及实战测试。还有一个优化思路是提高循环语句的效率,对比了for循环和while循环没有太大的差别,网上看到map方法和列表理解会比for循环快,但貌似这两个方法只局限于一些转换映射的操作,还没仔细了解。

四、抢票程序的共有思路

为女票抢票的程序从去年秋天就开始写,断断续续的,每次都是失败了才发现问题,因为抢票机会也不是总是有,所以实战机会少,优化迭代的速度也就慢,当然也是自己比较业余,没能想到前头。虽然这个抢票程序只有几行代码,十分简单,但是可以分享一下这么久以来学习抢票软件的思路。

中间我也查阅了很多其它抢票程序的写法(12306等),基本上都是用selenium,中间包括很多登录、验证的操作,各种点击、输入信息等,核心都是用循环进行刷新查询等,但是像微博私信这种没有一个具体的对象来点击或查询的,就需要有时间卡点的设计。

1、登录验证

很多抢票程序最复杂的地方,因为票方平台为了防止爬虫黄牛,会设计很多登录门槛和验证方式,所以很多程序实际上大部分的代码都在解决这个问题,进入以后核心的循环语句反而是很简单的,如果使用selenium就涉及selenium的鼠标操作、键盘操作,更难的可能还有图片识别。微博反而是简单的了,但其实如果不想费劲,可以降低自动化程度,在一些地方采用人工的方式,毕竟技术太难,抢票嘛,不寒碜……

2、时间卡点设计

我发现很多抢票程序并没有对开票时间进行时间卡点的设计,其实难度也不高,重点是要获取的是目标服务器的时间,因为不同的服务器时间会有略微的差别,不要直接用本地时间来操作。当然如果有一些可操作的元素,如点击按钮会在开始时间后出现,也可利用不断地刷新查找来解决。

3、循环语句

循环语句是抢票程序的核心,虽然它内容相对简单,但是它仍然是核心,将输入信息、查询、点击、时间卡点等操作嵌入循环中,就是一个基础的抢票程序。我看到一句话非常准确,大意是现在所谓抢票程序实际就是抢票的自动化。

自动化后依赖计算机的运行速度提高抢票的概率这就是抢票程序的核心思路,但要进一步提高抢的概率,就必须寻找更高效的方法。

对于简单的抢票程序而言,完成自动化或者半自动化(主要是循环语句部分的自动化)就已经足够了,当然适用性和便利性会大打折扣。

最后一个小tip

抢票程序会受到网速的影响,有一次在帮女票实战抢票中因为网速问题,两三秒才把私信发出去,真·不如手速,但所有抢票程序都会受到这个的影响,记得保持网络流畅!

python自动化(三):selenium微博抢票(含抢票程序设计思路)相关推荐

  1. Python 自动化:根据模板批量生成含指定数据的 word 文档

    作者:一只河马h 来源:简说Python 一.需求说明 在平时工作当中,经常需要处理文件,特别是Word,处理Word时会遇一类比较常见的场景:文档中大部分文字固定不变,小部分内容需要修改. 这时我们 ...

  2. Python自动化:根据模板批量生成含指定数据的word文档

    一.需求说明 在平时工作当中,经常需要处理文件,特别是Word,处理Word时会遇一类比较常见的场景:文档中大部分文字固定不变,小部分内容需要修改. 这时我们会机械的重复打开.修改.保存文档等一系列操 ...

  3. Python自动化问卷填写-问卷星(含完整代码)

    目录 一.环境安装 二.代码分析 (一)库的引用 (二)驱动的运行 (三)各类题型的程序 (四)主程序(根据问卷客制) 三.完整代码 由于网上的问卷星填写代码良莠不齐,搜索半天也没有一个可以正常运行, ...

  4. python selenium api_Selenium2+python自动化-查看selenium API

    前面都是点点滴滴的介绍selenium的一些api使用方法,那么selenium的api到底有多少呢?本篇就叫大家如何去查看selenium api,不求人,无需伸手找人要,在自己电脑就有. pydo ...

  5. wps python 自动化_Python3+Selenium+Chrome实现自动填写WPS表单

    引言 本文通过python3.第三方python库Selenium和谷歌浏览器Chrome,完成WPS表单的自动填写. 开发环境配置 python3的安装:略,网上都有教程. Selenium的安装: ...

  6. 【python自动化测试】京东|淘宝|秒杀12306抢票程序揭秘!一起薅羊毛吧【含源码】

    相信老铁们应该也看过很多这样的视频或者帖子:python自动秒杀的程序,京东,淘宝,大麦网抢票,秒杀抢购抢茅台,12306抢票,还有python薅羊毛的,感觉好像需求挺大的,很多人感兴趣.我也看了一些 ...

  7. python自动化(三)web自动化:2.web自动化工具selenium讲解

    一.selenium简介 1.什么是selenium Selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, ...

  8. python自动化控制运动_Python +selenium自动化帮你预订运动场地

    导语 炎热的夏天,正是换上短裤短裙晒身材的时候.但是,身材不好怎么办?运动是一个选择,特别是像我们程序员行业,天天坐在空调办公室,更应该出出汗,正所谓:冬练三九,夏练三伏. 下班后,约上公司的妹子,打 ...

  9. [Python人工智能] 三十四.Bert模型 (3)keras-bert库构建Bert模型实现微博情感分析

    从本专栏开始,作者正式研究Python深度学习.神经网络及人工智能相关知识.前一篇文章开启了新的内容--Bert,首先介绍Keras-bert库安装及基础用法及文本分类工作.这篇文章将通过keras- ...

最新文章

  1. 手机连接服务器传文件在哪里,手机云服务器传文件在哪里
  2. 非x面容解锁插件ios13_ios13近期消息汇总,苹果要放大招??
  3. Python 基础篇-简单的异常捕获
  4. 9名程序员被抓!这次真的活该.....
  5. UWP 检测网络状态
  6. 平均交付时长减少五天!腾讯TAPD助力企业高效交付!
  7. 使用SAP云平台Mobile Service开发移动应用
  8. jboss url路径_在JBoss的服务器端正确解码URL参数
  9. java mongodb 返回所有field_JAVA高级之反射
  10. 高带宽低性能服务器,国外大带宽低延迟服务器首选天下数据美国服务器
  11. html 透视效果,html – CSS – 对背景图像的“敲除”/透视效果
  12. ScrollView各属性,及代理方法汇总
  13. 记忆训练 0-100的110个数字对应编码
  14. 射频能量用于治疗和美容
  15. vscode 是干什么用的_vscode是干嘛用的
  16. linux拷贝4g以上文件夹,32位Ubuntu中支持超过4G的大内存的方法
  17. (2019春)软件构造:雨课堂试卷(一)
  18. 如何解决All flavors must now belong to a named flavor dimension.?
  19. 【LaTeX应用】LaTeX绘图
  20. 2013金山校园招聘Java笔试题

热门文章

  1. code: ‘MODULE_NOT_FOUND‘, Error: Cannot find module ‘cors‘
  2. 0040 基于文本界面的房屋出租系统
  3. Java美颜相机入门(图像处理实现各种滤镜算法)
  4. 三星李在镕召集半导体等部门高层举行战略会议 时间非同寻常
  5. CMDB配置管理的实施步骤
  6. 人们要怎样才能成为超级英雄?
  7. 附下载 | 《中国移动5G行业专网技术白皮书》
  8. 基于javaweb的医院住院管理系统(java+ssm+jsp+bootstrap+mysql)
  9. 如何快速给pdf添加水印?
  10. kubernetes persistentVolume 内存单位