STEAM购买游戏,支付宝或者微信
import base64
import json
import logging
import os
import sys
import time
# import qrcode
import requests
from lxml import etree
requests.packages.urllib3.disable_warnings()
from steam_master.steam.client import SteamClient
from steam_master.steam.enums import EResult
logging.basicConfig(
level=logging.INFO, # 定义输出到文件的log级别,大于此级别的都被输出
format='%(asctime)s %(filename)s %(levelname)s : %(message)s', # 定义输出log的格式
datefmt='%Y-%m-%d %H:%M:%S', # 时间
filename="{}\\steam_cd_key.log".format(os.path.dirname(os.path.abspath(__file__))), # log文件名
filemode='a') # 写入模式“w”或“a”
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# 设置格式
formatter = logging.Formatter('%(asctime)s %(filename)s %(levelname)s : %(message)s')
# 告诉handler使用这个格式
console.setFormatter(formatter)
# 为root logger添加handler
logging.getLogger('').addHandler(console)
def steam_bind(username, password=None, auth_code=None, two_factor_code=None, user_sentry=None, file_path=None, payment="alipay", app_origin_id=None, file_path_QR=None):
logging.info('username={}, auth_code={}, two_factor_code={}, user_sentry={}, file_path={}, payment={}, app_origin_id={}'.format(username, auth_code, two_factor_code, user_sentry, file_path, payment, app_origin_id))
item = {}
if password == '0':
password = None
if auth_code == '0':
auth_code = None
if two_factor_code == '0':
two_factor_code = None
if user_sentry == '0':
user_sentry = None
if file_path == '0':
file_path = None
item["username"] = username
item["app_origin_id"] = app_origin_id
if file_path is not None:
file_path = file_path
else:
file_path = "{}\\purchase.json".format(os.path.dirname(os.path.abspath(__file__)), username)
if file_path_QR is not None:
file_path_QR = file_path_QR
else:
file_path_QR = "{}\\QR_code.jpg".format(os.path.dirname(os.path.abspath(__file__)))
file_path_sentry = "{}\\".format(os.path.dirname(os.path.abspath(__file__)))
if user_sentry is not None:
with open("{}{}_sentry.bin".format(file_path_sentry, username), 'wb') as f:
f.write(base64.b64decode(user_sentry))
client = SteamClient()
client.set_credential_location(file_path_sentry)
result = client.login(username=username, password=password, auth_code=auth_code, two_factor_code=two_factor_code)
if result == EResult.InvalidPassword:
item["code"] = 4
item["message"] = "账号或密码错误:"
elif result in (EResult.AccountLogonDenied, EResult.InvalidLoginAuthCode):
if result == EResult.AccountLogonDenied:
item["code"] = 5
item["message"] = "请输入邮箱验证码:"
else:
item["code"] = 6
item["message"] = "验证码不正确:请重新输入邮箱验证码:"
elif result in (EResult.AccountLoginDeniedNeedTwoFactor, EResult.TwoFactorCodeMismatch):
if result == EResult.AccountLoginDeniedNeedTwoFactor:
item["code"] = 7
item["message"] = "请输入手机验证码:"
else:
item["code"] = 8
item["message"] = "验证码不正确:请重新输入手机验证码:"
elif result == EResult.OK:
item["code"] = 12
item["message"] = "steam登入成功:开始购买游戏:"
logging.info("用户{}:登入成功".format(username))
try:
with open("{}{}_sentry.bin".format(file_path_sentry, username), 'rb') as f:
user_sentry = f.read()
except:
user_sentry = b'user is not bound steam'
item['user_sentry'] = base64.b64encode(user_sentry).decode('utf-8')
app_origin_id = app_origin_id
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36",
}
# 一键公开
session = client.get_web_session() # 获取session
game_html = session.get("https://store.steampowered.com/app/{}".format(app_origin_id), verify=False).content.decode('utf-8') # proxies=REQUESTS_PROXIES
etree_html = etree.HTML(game_html)
add_data = {}
try:
add_data['snr'] = etree_html.xpath('//div[@class="game_area_purchase_game"]/form[@method="POST"]/input[@name="snr"]/@value')[0]
add_data['originating_snr'] = etree_html.xpath('//div[@class="game_area_purchase_game"]/form[@method="POST"]/input[@name="originating_snr"]/@value')[0]
add_data['action'] = etree_html.xpath('//div[@class="game_area_purchase_game"]/form[@method="POST"]/input[@name="action"]/@value')[0]
add_data['sessionid'] = etree_html.xpath('//div[@class="game_area_purchase_game"]/form[@method="POST"]/input[@name="sessionid"]/@value')[0]
add_data['subid'] = etree_html.xpath('//div[@class="game_area_purchase_game"]/form[@method="POST"]/input[@name="subid"]/@value')[0]
except:
item["code"] = 13
item["message"] = "游戏是免费游戏或者你已经拥有这个游戏:"
add_data['snr'] = ''
logging.info("游戏是免费游戏或者你已经拥有这个游戏")
# print("{}".format(data))
if add_data['snr']:
# try:
logging.info(json.dumps(add_data, ensure_ascii=False))
logging.info('*' * 100)
cart_html = session.post("https://store.steampowered.com/cart/", data=add_data, verify=False).content.decode('utf-8')
etree_html = etree.HTML(cart_html)
btn_purchase_self_url = etree_html.xpath('//*[@id="btn_purchase_self"]/@href')[0]
self_html = session.get(btn_purchase_self_url, verify=False).content.decode('utf-8')
self_etree_html = etree.HTML(self_html)
mode_data = {}
try:
mode_data['gidShoppingCart'] = self_etree_html.xpath('//*[@id="shopping_cart_gid"]/@value')[0]
except:
mode_data['gidShoppingCart'] = -1
try:
mode_data['gidReplayOfTransID'] = self_etree_html.xpath('//*[@id="gid_replay"]/@value')[0]
except:
mode_data['gidReplayOfTransID'] = -1
mode_data['PaymentMethod'] = payment
mode_data['abortPendingTransactions'] = 0
mode_data['bHasCardInfo'] = False
mode_data['CardNumber'] = ''
mode_data['CardExpirationYear'] = ''
mode_data['CardExpirationMonth'] = 0
mode_data['sessionid'] = add_data['sessionid']
mode_data['shopping_cart_gid'] = self_etree_html.xpath('//*[@id="shopping_cart_gid"]/@value')[0]
mode_of_payment = session.post("https://store.steampowered.com/checkout/inittransaction/", data=mode_data, verify=False).content.decode('utf-8')
if json.loads(mode_of_payment)['success'] == 1:
mode_data['transid'] = json.loads(mode_of_payment)['transid']
logging.info(json.dumps(mode_data, ensure_ascii=False))
logging.info("*" * 100)
get_final_price = session.get("https://store.steampowered.com/checkout/getfinalprice/?count=1&transid={}&purchasetype=selfµtxnid=-1&cart={}&gidReplayOfTransID=-1".format(mode_data['transid'], mode_data['shopping_cart_gid']), verify=False).content.decode('utf-8') # proxies=REQUESTS_PROXIES
logging.info(json.dumps(get_final_price))
get_final_price = json.loads(get_final_price)
if get_final_price['success'] == 1:
item['original_price'] = int(get_final_price['base']) / 100
item['discount'] = int(get_final_price['discount'])
if item['discount'] != 0:
item['discount'] = item['discount'] / 100
item['real_price'] = int(get_final_price['total']) / 100
item['integral'] = get_final_price['lineitems'][0]['loyaltypoints']
payment_html = session.get("https://store.steampowered.com/checkout/externallink/?transid={}_external_provider".format(mode_data['transid']), verify=False).content.decode('utf-8') # 支付跳转
# print(payment_html)
# print('*' * 100)
payment_etree_html = etree.HTML(payment_html)
payment_data = {}
payment_url = payment_etree_html.xpath('//*[@id="externalForm"]/@action')[0]
payment_data['MerchantID'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="MerchantID"]/@value')[0]
payment_data['MerchantTransactionID'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="MerchantTransactionID"]/@value')[0]
payment_data['Amount'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Amount"]/@value')[0]
payment_data['Currency'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Currency"]/@value')[0]
payment_data['ReturnURL'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="ReturnURL"]/@value')[0]
payment_data['MethodID'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="MethodID"]/@value')[0]
payment_data['Country'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Country"]/@value')[0]
payment_data['CustomerEmail'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="CustomerEmail"]/@value')[0]
payment_data['CustomerName'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="CustomerName"]/@value')[0]
payment_data['SkipHPP'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="SkipHPP"]/@value')[0]
if payment == 'alipay':
payment_data['Articles'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Articles"]/@value')[0]
payment_data['Description'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Description"]/@value')[0]
payment_data['SkinID'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="SkinID"]/@value')[0]
payment_data['Hash'] = payment_etree_html.xpath('//*[@id="externalForm"]/input[@name="Hash"]/@value')[0]
logging.info(json.dumps(payment_data, ensure_ascii=False))
logging.info("*" * 100)
payments_html = session.post(payment_url, data=payment_data, verify=False, headers=headers)
if payment == 'alipay':
alipay_html = payments_html.content.decode('gbk')
logging.info(payments_html.url)
logging.info("*" * 100)
logging.info(payments_html.headers)
logging.info("*" * 100)
alipay_etree_html = etree.HTML(alipay_html)
alipay_code = alipay_etree_html.xpath('//*[@id="J_qrCode"]/@value')[0]
item['payment_link'] = alipay_code
logging.info(alipay_code)
logging.info("*" * 100)
# img = qrcode.make(alipay_code)
# img.save(file_path_QR)
# logging.info("二维码生成成功,请支付付款")
else:
wechat_html = payments_html.content.decode('utf-8')
logging.info(payments_html.url)
logging.info("*" * 100)
wechat_etree_html = etree.HTML(wechat_html)
wechat_code = wechat_etree_html.xpath('//*[@id="QRCodeImageControl"]/img/@src')[0]
item['payment_link'] = wechat_code
logging.info(wechat_code)
logging.info("*" * 100)
# with open(file_path_QR, 'wb') as file:
# img = base64.b64decode(wechat_code.replace("data:image/gif;base64,", ""))
# file.write(img)
# logging.info("二维码生成成功,请支付付款")
item["code"] = 17
item["message"] = "支付链接已经生成(微信是二维码base64编码,支付宝是支付链接):app_origin_id:{}".format(app_origin_id)
try:
with open(file_path, 'w') as f:
json.dump(item, f)
logging.info("文件写入成功")
except Exception as e:
logging.info("文件写入错误:{}".format(e))
for i in range(1200):
transaction_status = session.get("https://store.steampowered.com/checkout/transactionstatus/?count=1&transid={}".format(mode_data['transid'])).content.decode('utf-8')
logging.info("i:{}, transaction_status:{}".format(i, json.dumps(transaction_status)))
logging.info("*" * 100)
time.sleep(2)
if json.loads(transaction_status)['success'] == 1:
logging.info("{} 购买游戏成功:app_origin_id:{}".format(username, app_origin_id))
item["code"] = 200
item["message"] = "{} 购买游戏成功:app_origin_id:{}".format(username, app_origin_id)
break
if i == 600:
logging.info("{} 购买游戏失败:app_origin_id:{} 请重新购买".format(username, app_origin_id))
item["code"] = 14
item["message"] = "{} 购买游戏失败:app_origin_id:{} 请重新购买".format(username, app_origin_id)
break
break
else:
logging.info("前面购买这个这个游戏失败或支付为成功请重新购买 app_origin_id:{}".format(app_origin_id))
item["code"] = 16
item["message"] = "前面购买这个这个游戏失败或支付为成功请重新购买 app_origin_id:{}".format(app_origin_id)
else:
logging.info("过去几个小时内尝试了多次购买。请在重试前稍等片刻")
item["code"] = 15
item["message"] = "过去几个小时内尝试了多次购买。请在重试前稍等片刻"
# except:
# item['code'] = 14
# item["message"] = "username:{} 购买游戏失败:app_origin_id:{} 请重新购买".format(username, app_origin_id)
# logging.info("游戏购买失败")
try:
logging.info("{}{}_sentry.bin".format(file_path_sentry, username))
os.remove("{}{}_sentry.bin".format(file_path_sentry, username))
logging.info("删除文件成功:{}{}_sentry.bin".format(file_path_sentry, username))
except Exception as e:
logging.info("删除用户认证文件异常:{}".format(e))
client.logout()
logging.info('username:{}, message:, auth_code:{}, two_factor_code:{}, code:, result:{}'.format(username, auth_code, two_factor_code, result))
elif result == EResult.RateLimitExceeded:
item["code"] = 10
item["message"] = "请求频率过高,请稍后在请求:"
else:
item["code"] = 99
item["message"] = "未知错误"
item["result"] = result
item["username"] = username
try:
with open(file_path, 'w') as f:
json.dump(item, f)
logging.info("文件写入成功")
except Exception as e:
logging.info("文件写入错误:{}".format(e))
logging.info("item:{}".format(item))
if __name__ == "__main__":
# steam_bind('17682303516', 'Yu1064145110', payment="alipay", app_origin_id="1168660")
# steam_bind('yoyo12165', 'Yu1064145110', payment="wechat", app_origin_id="1168660")
# steam_bind('17682303516', 'yu1064145110', file_path="{}\\{}_info.json".format(os.path.dirname(os.path.abspath(__file__)), "uname"))
steam_bind(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7], sys.argv[8], sys.argv[9])