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])