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

2023-11-08

缘起

这个故事起源于女票是一个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()
            break
        else:
            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()
        break
    else:
        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.headers
        print(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.headers
    if tt_2 - tt_1 <=1:
        print(header['Date'],a)
        a+=1
    else:
        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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • Windows Server 2019,开启多用户远程

    Windows Server 2019 开启多用户远程 最后记得重启计算机
  • DevopsCamp 第 2 期作业: 《cobra - 05 Cobra 的子命令》 简单说下 cobra 命令树和 gin 路由树的实现差异

    DevopsCamp 第 2 期作业 cobra 05 Cobra 的子命令 简单说下 cobra 命令树和 gin 路由树的实现差异 原文链接 https typonotes com posts 2023 02 14 devopscamp
  • PCL 体素滤波(C++详细过程版)

    体素滤波 一 概述 二 代码实现 三 结果展示 1 原始点云 2 滤波结果 一 概述 体素滤波PCL中经典的点云下采样算法 具体算法原理和实现代码见 PCL体素滤波器 为充分了解算法实现的每一个细节和有待改进的地方 使用C 代码对算法实现过
  • 力扣题---二叉树---相同的树

    题目连接 相同的树 首先我看题目要求以及例题 给你两棵二叉树的根节点 p 和 q 编写一个函数来检验这两棵树是否相同 如果两个树在结构上相同 并且节点具有相同的值 则认为它们是相同的 示例 1 输入 p 1 2 3 q 1 2 3 输出 t
  • FeignClient接口的几种方式总结

    FeignClient这个注解 已经封装了远程调用协议 在springboot的开发 或者微服务的开发过程中 我们需要跨服务调用 或者调用外部的接口 我们都可以使用FeignClient 一 FeignClient介绍 FeignClien
  • ChatGLM2-6B本地部署

    ChatGLM2 6B本地部署 ChatGLM2 6B 是开源中英双语对话模型 ChatGLM 6B 的第二代版本 在保留了初代模型对话流畅 部署门槛较低等众多优秀特性的基础之上 ChatGLM2 6B 引入了如下新特性 更强大的性能 基于
  • uniapp截取部分区域

    通过canvas来绘制截取部分 然后保存 html部分
  • 手把手教你,Selenium 遇见伪元素该如何处理?

    问题发生 在很多前端页面中 大家会见到很多 before after 元素 比如 百度流量研究院 比如 百度疫情大数据平台 以 百度疫情大数据平台 为例 累计确诊 文本并没有显示在 HTML 源代码中 如果通过常规的 xpath 元素定位方
  • Java 经典面试题:聊一聊 JUC 下的 LinkedBlockingQueue

    本文聊一下 JUC 下的 LinkedBlockingQueue 队列 先说说 LinkedBlockingQueue 队列的特点 然后再从源码的角度聊一聊 LinkedBlockingQueue 的主要实现 LinkedBlockingQ
  • c++中的关联容器

    c 中的关联容器主要是map set 已经multimap multiset 为了讲map 得先将pair类型 pair就是一个两个类型的组合 比如一个人的学号就可以是pair
  • 【重磅最新】163篇ICML-2021强化学习领域论文整理汇总(2021.06.07)

    深度强化学习实验室 官网 http www neurondance com 论坛 http deeprl neurondance com 作者 深度强化学习实验室 来源 整理自https icml cc ICML 是机器学习领域最重要的会议
  • 【python爬虫专项(25)】新型冠状病毒肺炎B站视频弹幕数据爬并做数据词云展示

    1 查看要爬取页面 打开B站网址 输入 新型冠状病毒肺炎 关键字 显示界面如下 2 确定爬虫逻辑 查看网页的内容后 一个网址页面下20个视频 这里只采集20页的视频数据 共400个视频 因为是出现的视频按照点击量进行排序的 所以再往后的视频
  • Java使用多线程异步执行批量更新操作

    写在前面 相信不少开发者在遇到项目对数据进行批量操作的时候 都会有不少的烦恼 尤其是针对数据量极大的情况下 效率问题就直接提上了菜板 因此 开多线程来执行批量任务是十分重要的一种批量操作思路 其实这种思路实现起来也十分简单 就拿批量更新的操
  • 观察者模式(Observer)

    一 观察者模式定义 对象间的一种一对多的依赖关系 当一个对象的状态发生改变时 所有依赖它的对象都得到通知并自动更新 二 观察者模式的结构说明 1 Subject 目标对象 a 一个目标可以被多个观察者观察 b 目标可以提供添加和删除观察者
  • Linux usb gadget框架概述

    大大小小开发了四个与gadget相关的驱动 字符驱动 g multi g ether g zero 在这里把自己对gadget的开发中自己的感悟记录之 想要了解gadget 必须了解其框架 知道composite gadget udc三者之
  • Vue+百度统计 实现网页的PV和UV统计

    目录 什么是PV和UV 百度统计 VUE 验证安装 查看统计 拓展 什么是PV和UV 这里我懒得打字了 直接百度扒过来吧 这个了解知道是啥就行 百度统计 首先你要有个百度账号 自己测试的时候可以用自己的百度个人账户 项目里向公司申请企业商业
  • JAVA byte类型转String类型

    问题 RSA加密 byte类型转String类型 格式转换之后内容变了 解密解不出来 第一种方式 使用 ISO 8859 1 编码 使用此方式编码返回结果会乱码 例如 public static void main String args
  • 超详细Shell学习教程第四篇shell脚本参数化

    目录 1 1参数化实例 1 2参数处理说明 1 3带返回值的参数 书写带参数的shell脚本 1 1参数化实例 创建bash1 sh bin bash echo Shell 传递参数实例 echo 第一个参数为 1 echo 参数个数为 e
  • 学习swoole框架需要杀掉9501进程,强制的解决办法

    1 查看进程 我们运行一下命令 netstat anp grep 9501 2 看出进程29698占用的9501端口 3 强制杀死进程 kill 9 29698 强制
  • python自动化(三):selenium微博抢票(含抢票程序设计思路)

    缘起 这个故事起源于女票是一个bjd娃圈爱好者 我才知道在娃圈里经常通过微博私信的方式进行一些商品的交易 例如娃娃的面妆 衣服和娃娃本身 这就引发了抢票需求 流程 在某一个整的时间点进行微信的私信发送 排名靠前者获得 人工操作反应慢 只能提