zoukankan      html  css  js  c++  java
  • 【Python】自动化抢购茅台,真香。

    前言

    全民抢购茅台,导致中证白酒指数一路飙升… 跟着大牛喝汤的同时,我也参与了抢购,抢到就是赚到,年关将至,就算自己不喝送礼也是非常 nice 的。

    各大平台基本都有抢购茅台的活动,作为互联网从业人员,大家都知道通过前端手动抢购太慢了,避开前端直接通过接口对服务器发起请求会大大增加抢购的效率。GitHub 上就有大佬开源的抢购项目,本着学习的态度,对代码仔细阅读和研究。学习过程中也发现了一些问题,并尝试进行完善。下文分享学习过程中遇到的问题,以及解决办法。

    原理

    首先来看下,实际用户抢购的步骤(某东为例):

    • 登录某东商城客户端

    • 进入商品详情页

    • 预约商品

    • 在指定时间进行抢购

    程序的实现逻辑也是如此,通过代码的方式一步一步去实现它。

    运行环境 Python 3.7.3

    1. 登录某东商城客户端

    • 访问 WEB 登录页面,爬取登录二维码保存

    • 将图片弹出,用户手动扫码后去循环刷新登录状态,获取用户身份标识 token/cookies/ticket

    2. 进入商品详情页

    • 根据商品 ID,获取商品详情页面链接,预约链接

    3. 预约商品

    • 用户身份标识 + 预约链接,完成预约

    4. 在指定时间进行抢购

    • 通过电脑时间跟某东服务器时间进行比对,在开放抢购前 500 毫秒发起请求

    • 为快速进行请求,同时开启 5 个线程去访问

    • 为保证程序稳定,循环开启线程时设置时间间隔

    准备

    1. 程序运行依赖一些第三方库,需要提前安装(用的清华源,速度会快一点);

    pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
    

    2. 获取用户标识(必填参数);

    • 进入某东商城 WEB 页面,选择一个可下单的商品

    • 进入开发者模式console栏,输入_JdTdudfp,然后在页面上点击下单

    • 将获取到的eidfp写入配置文件内

    使用

    直接运行 main.py,根据提示选择就行,程序入口代码如下,非常简单。

    jd_seckill = JdSeckill()
    choice_function = input('请选择:')
    if choice_function == '1':   # 预约 
        jd_seckill.reserve()
    elif choice_function == '2':  # 抢购
        jd_seckill.seckill_by_proc_pool()  
    else:
        print('没有此功能')
        sys.exit(1)
    

    需要整个项目原代码后台回复「抢购

    改动

    我在原项目的基础上又做了一些改动,其中部分问题已经有人提 issues 了,但是作者还没来得及改,有些是我根据自己的喜好修改的。

    问题 1:

    拿到代码后直接从根目录执行 main.py 文件时,报异常:FileNotFoundException

    原因:读取配置文件时,没有使用绝对路径,使用 abspath 替换并拼接后,解决该问题

    问题 2:

    预约和抢购需要执行两次 main.py 文件,分别输入 1、2 完成对应操作

    原因:这个其实作者设计如此,但是我的预期是执行文件后,直接帮我预约,预约完成后进行抢购,所以我把运行入口代码修改了,执行一次即可

    问题 3:

    预约逻辑问题,某东预约是每天 10 点 30 分以后即可预约,但是程序设计为必须到达抢购时间才可预约,也就是抢购前 500 毫秒

    修改:当前时间大于 10 点 30,即可进行预约

    问题 4:

    抢购时间需要每次在配置文件内手动修改为当天,如果不修改会判断当前时间永远大于抢购时间,出现只要运行程序就发起抢购的问题

    修改:增加当天时间自动获取,如果在 10 点前运行程序,则等待到达抢购时间;如果在 10 点 30 分后手动运行程序,则直接提示抢购时间已过,不再发起请求;针对两种情况区分了提示信息

    问题 5:

    原程序是没有自动终止的,比如抢购 2 分钟后,结果已经就如此了,往后再抢购意义不大,需要手动去终止程序

    解决:增加了一个杀死进程的方法,需要配合定时任务使用

    问题 6:

    抢购过程中,多进程处理时,都增加了商品名称和用户名获取的逻辑

    优化:取消掉该逻辑,因为抢购的商品就一个,所以程序运行前去获取一次就可以了

    问题 7:

    抢购过程中出现了一次「当前地区无货」的情况,无法从日志看出问题

    解决:增加了这种情况下的逻辑判断和日志打印

    问题 8:

    日志格式过长,打开日志文件,当前屏看到的都是格式,需要左滑才能看到真正的日志

    解决:修改日志 formatter 格式,精简信息

    问题 9:

    日志文件根据存储大小来进行判断是否备份,每天的抢购信息不好区分

    优化:根据日期,每天一个日志文件,最多做 5 天备份,超出则删除最早一天的日志文件

    问题 10:

    作者使用了 serverChan 进行推送抢购结果到微信,该方法在多线程内,每抢购一次就发送一次消息,调用次数过于频繁,导致有时被服务拉黑(server酱对发送消息有限制,每人每天上限 500 条,相同内容 5 分钟内不能重复发送,不同内容 10 分钟内不能连续发送,每天调用接口超过1000次的用户将被系统自动拉黑)所以其实发送这么频繁,真正收不到几条消息

    解决:修改发送消息逻辑,改为定时任务,获取到最终结果后,再发送消息,预约一条,抢购结果一条。由于微信上推送的内容是仅展示标题,作者是把标题写死了,所以需要点击「查看详情」才能查看结果,为了少点那一下,我就把结果直接改为标题,真的要查看详细信息了再去点击。

    定时任务

    该脚本配合定时任务,不再需要每天掐着点去抢购啦

    # [Python] jd seckill maotai
    55 09 * * * /usr/bin/python3 workspace/jd_seckill/main.py
    
    # [Python] Stop Python Process
    02 10 * * * /usr/bin/python3 workspace/jd_seckill/seckill_stop.py
    
    # [Python] Send wechat message by serverChan
    03 10 * * * /usr/bin/python3 workspace/jd_seckill/util.py
    

    如果需要我修改后的代码,后台回复「加油

    其实脚本抢购是次要的,因为在某东各种风控的限制下,抢购速度并不是第一位的,重在参与,结果倒是无所谓了... 如果能从开源脚本中学到一点东西,那么才是真的赚呢。

    感谢阅读。

    end

    
    
  • 相关阅读:
    linux 查看安装软件位置(持续跟新)
    POJ 3661 Running (DP思想)
    stringstream的用法
    关于实验室搬家
    POJ 搜索(2)
    Treap的插入删除实现
    碰到一道不错的扩展欧几里德题目 whu 1338
    SRM 144
    关于无向图双连通问题
    POJ 动态规划(2)
  • 原文地址:https://www.cnblogs.com/finer/p/14488312.html
Copyright © 2011-2022 走看看