- 该脚本涉及加密和网络请求,这可能受到法律和道德的限制,特别是在自动化购买(秒杀)和自动登录等领域。使用此类脚本可能违反服务提供商的使用条款。- 秒杀行为可能对服务器造成压力,且在竞争激烈的情况下可能会导致账户被暂时或永久封禁。
建议
仅用于学习和研究目的。
话不多说,直接先上代码
import base64
import random
import time
import requests
import functools
import json,sys,hashlib
import os
import pickle
import urllib.parse
import multiprocessing
from encrpty import *
from mi_logger import logger
from timer import Timer
from config import global_config
from concurrent.futures import ProcessPoolExecutor
from util import (
parse_json,
send_wechat,
wait_some_time,
get_random_useragent
)
"""
主要用到的加密算法有两个:
1、登录接口的加密算法,包括请求头和body,具体加密逻辑在其他文件。
2、抢购、预约的入参加密,包括 yp-srs、 yp-ss、 yp-srt三个值。
具体加密逻辑比较敏感,暂不公开。
"""
class MiSeckill(object):
def __init__(self , user_name):
# 初始化信息
self.act_id = global_config.getRaw('config', 'act_id')
self.timers = Timer()
self.spider_session = SpiderSession(user_name)
self.spider_session.load_cookies_from_local()
self.login = Login(self.spider_session,user_name)
self.session = self.spider_session.get_session()
self.user_agent = self.spider_session.user_agent
self.locationUrl = None
def login_by_accountAndPassword(self):
"""
登陆
:return:
"""
if self.login.is_login:
logger.info('登录成功')
return
self.login.login_by_accountAndPassword()
if self.login.is_login:
#将cookie记录在本地
self.spider_session.save_cookies_to_local(self.login.nickName)
else:
raise logger.error("账号密码登录失败!")
def check_login(func):
"""
用户登陆态校验装饰器。若用户未登陆,则调用登陆
"""
@functools.wraps(func)
def new_func(self, *args, **kwargs):
if not self.login.is_login:
self.login_by_accountAndPassword()
return func(self, *args, **kwargs)
return new_func
@check_login
def appoint(self):
"""
预约
"""
self._appoint()
def getSignByData(self,data):
#核心加密,隐藏
pass
re ={
'yp-srt':xxx,
'yp-srs': xxx,
'yp-ss': xxx
}
return re
def isAppoint(self):
# 核心代码隐藏
pass
re = self.session.post("xxxxxxxxxxxxx",
data=json.dumps(data), headers=header)
if re.json().get('code') == 0 and re.json().get('success') and re.json().get('data').get('userStatusInfo'):
return re.json().get('data').get('userStatusInfo').get('ordered')
else:
logger.error('获取今日商品信息出错,程序继续执行。')
return False
def _appoint(self):
self.getTodayActid()
if self.isAppoint() :
logger.info("---------您已预约成功,无需再次预约!----------")
return True
nowtime = int(round(time.time() * 1000))
data = [{}, {"actId": self.act_id, "tel": ""}]
#获取校验所需加密参数
signDict = self.getSignByData(data)
headerPhone = {
"accept": "*/*"
, "accept-encoding": "gzip, deflate, br"
, "accept-language": "zh-CN,zh;q=0.9"
, "content-type": "application/json"
,"referer": self.locationUrl
,"user-agent": self.user_agent
, "X-Requested-With": "XMLHttpRequest"
, "yp-srs": signDict['yp-srs']
, "yp-ss": signDict['yp-ss']
, "yp-srt": signDict['yp-srt']
}
re = self.session.post("https://m.xiaomiyoupin.com/mtop/act/orderspike/order?_=" + str(nowtime),
data=json.dumps(data),headers=headerPhone)
if json.loads(re.text).get("code") == 0 and json.loads(re.text).get("success") == True:
logger.info("---------预约成功,记得按时抢购哦!----------")
logger.info("当前预约人数为:{}".format(json.loads(re.text).get("data").get("orderCount") ))
return True
else:
logger.info("预约失败,返回结果为:{}".format(json.loads(re.text)))
return False
@check_login
def seckill(self):
"""
抢购
"""
self._seckill()
def seckill_by_proc_pool(self, work_count=1):
"""
多进程进行抢购
work_count:进程数量
"""
multiprocessing.freeze_support()
with ProcessPoolExecutor(work_count) as pool:
for i in range(work_count):
pool.submit(self.seckill)
def getUserlevel(self):
try :
# 核心代码隐藏
pass
re = self.session.post("xxxx", data=json.dumps(data),
headers=header)
re = re.json().get("data").get("userLevelVO")
# logger.info(re)
if re:
logger.info("获取用户品值为:"+str(re.get("score"))+", 活跃度:"+str(re.get("activity"))+
", 名誉值:"+str(re.get("reputation")))
except Exception as e :
logger.error("获取用户品值出现异常【{}】".format(e))
def getTodayActid(self):
try :
#核心代码隐藏
pass
###返回302转跳链接
if re.headers.get('Location'):
self.locationUrl = re.headers.get('Location')
urlparse = urllib.parse.urlparse(self.locationUrl)
query_dict = urllib.parse.parse_qs(urlparse.query)
self.act_id = query_dict.get('actId')[0]
logger.info("获取到今日飞天茅台商品id为 -----> {}".format(self.act_id))
##访问一次抢购页面
self.session.get(self.locationUrl)
except Exception as e :
logger.error("获取当天商品id出错:{}".format(e))
def _seckill(self):
"""
抢购
"""
a=0
while True:
try:
self.getUserlevel()
self.getTodayActid()
self.timers.start()
while True:
logger.info("第{}次抢购。".format(a))
flag = self.startKill()
#抢购成功直接返回,失败继续
if flag :
return
a = a + 1
wait_some_time()
if a>15 :
logger.info('抢购失败,明天继续努力。')
return
except Exception as e:
logger.info('抢购发生异常,稍后继续执行!', e)
wait_some_time()
def startKill(self):
data = [{}, {"actId": self.act_id,
"token": self.act_id}]
reDict = self.getSignByData(data)
trustType = xxx
headerPhone = {
"accept": "*/*"
, "accept-encoding": "gzip, deflate, br"
, "accept-language": "zh-CN,zh;q=0.9"
, "content-type": "application/json"
,"referer": self.locationUrl
,"user-agent": self.user_agent
, "X-Requested-With": "XMLHttpRequest"
, "c": xxxx
, "d": xxxx
, "yp-srs": reDict['yp-srs']
, "yp-ss": reDict['yp-ss']
, "yp-srt": reDict['yp-srt']
}
re = self.session.post("https://m.xiaomiyoupin.com/mtop/act/orderspike/ekips?_=" + str(int(time.time() * 1000)),
data=json.dumps(data), headers=headerPhone)
if json.loads(re.text).get("code") == 0 :
if json.loads(re.text).get("data").get("success"):
logger.info("-------------成功啦,请作者喝杯咖啡吧!!!---------------")
return True
logger.info("抢购失败:【{}】".format(re.text.strip()))
return False
说明
这个脚本是一个用于小米有品的秒杀助手,基于 Python 编写,使用了多个库和工具来处理登录、预约、和秒杀流程。下面详细解析各部分的功能和工作机制:
导入的库和模块
- 'base64', 'random', 'time', 'requests', 'functools', 'json', 'sys', 'hashlib', 'os', 'pickle', 'urllib.parse', 'multiprocessing': 这些是Python标准库,用于处理数据编码、时间操作、网络请求、功能扩展、数据序列化和并行计算。
- 'encrpty', 'mi_logger', 'timer', 'config', 'util': 这些是自定义模块,分别处理加密、日志记录、计时、配置管理和一些实用功能,如解析JSON、发送微信通知、等待随机时间、获取随机用户代理等。
核心类:'MiSeckill'
这个类是秒杀流程的主体,包含了登录、预约、秒杀等功能的实现。
- 初始化 ('__init__'): 设置活动ID、计时器、会话管理、用户代理等。
- 登录 ('login_by_accountAndPassword'): 尝试通过账号和密码登录,并在成功后保存cookie到本地。
- 登录校验装饰器 ('check_login'): 一个装饰器,用于确保在执行任何需要登录的操作前用户已经登录。
- 预约 ('appoint'): 执行预约动作,如果用户已经预约则不再重复预约。
- 获取签名 ('getSignByData'): 用于生成请求的签名,这是秒杀中防止请求伪造的关键步骤,实现细节未公开。
- 检查预约状态 ('isAppoint'): 检查用户是否已经成功预约。
- 执行预约 ('_appoint'): 包含获取当日活动ID和检查预约状态的逻辑。
- 秒杀 ('seckill'): 执行秒杀动作。
- **多进程秒杀** ('seckill_by_proc_pool'): 使用多进程来同时执行多个秒杀任务,提高成功率。
- 获取用户等级 ('getUserlevel'): 获取用户在小米有品上的等级和其他相关信息,可能用于优先级判断。
- 获取当日活动ID ('getTodayActid'): 获取当天的活动ID,这是进行秒杀所必需的。
- 实际执行秒杀 ('_seckill'): 包括用户等级获取、活动ID获取、以及反复尝试秒杀的循环逻辑。
- 开始秒杀 ('startKill'): 根据提供的数据生成签名,构造请求头,然后发送秒杀请求。
实际使用
这个脚本配置了多线程运行方式,可以为每个账户创建一个独立的线程,从而同时执行多个秒杀任务。使用了ProcessPoolExecutor来管理进程池,这是Python 'concurrent.futures'模块的一部分,用于简化并行执行的复杂性。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们,我们会第一时间更新。
暂无评论内容