You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

json.loads(response.stdout)在Windows失效,Linux正常求解决

问题

在Windows系统运行Python代码时,执行json.loads(response.stdout)持续报错,但该代码在Linux系统可正常运行,经排查未找到原因,需兼容Linux和Windows的解决方案。

完整代码如下:

# -------------------Config------------------

archive_prefix = "output"
output_txt_file = "output.txt"
output_html_file = "index.html"
archive_directory = "./archive"  # You may enter a relative path (folder needs to start with ./) or you can use a specific path (C:\folder\folder2\)
# Delete or rename old files based on the value of DeleteOldItems variable
DeleteOldItems = False  # If false, old items will be stacked in another location
OutputHTML = True  # Output as an HTML file so you can open it in a browser and click on the links
HostHTML = False  # If OutputHTML = True and HostHTML = True will host on all IPs on port 8080 (to reach if hosted on a personal computer, you can access using localhost:8080 as a URL in your web browser))

# ----------------End config-----------------

import subprocess
import json
import os
from datetime import datetime

# Get the number of times to loop from user input
num_loops = int(input("How many codes would you like?\n>> "))
index = 0  # Do not change

print("")
if DeleteOldItems:
  # Delete old files if they exist
  if os.path.exists(output_txt_file):
    os.remove(output_txt_file)
  if os.path.exists(output_html_file):
    os.remove(output_html_file)
else:
  # Rename old files with timestamp if they exist
  timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
  if os.path.exists(output_txt_file):
    new_txt_file = os.path.join(archive_directory,
                                f"{archive_prefix}_{timestamp}.txt")
    os.makedirs(os.path.dirname(new_txt_file), exist_ok=True)
    os.rename(output_txt_file, new_txt_file)
    print(f"Old output stored as {archive_prefix}_{timestamp}.txt")
  if os.path.exists(output_html_file):
    new_html_file = os.path.join(archive_directory,
                                 f"{archive_prefix}_{timestamp}.html")
    os.makedirs(os.path.dirname(new_html_file), exist_ok=True)
    os.rename(output_html_file, new_html_file)
    print(f"Old output stored as {archive_prefix}_{timestamp}.html")
# Initialize an empty list to store tokens
tokens = []

# Loop the specified number of times
for _ in range(num_loops):
  # Send the POST request using cURL
  curl_command = [
      'curl', 'https://api.discord.gx.games/v1/direct-fulfillment', '-H',
      'authority: api.discord.gx.games', '-H', 'accept: */*', '-H',
      'accept-language: en-US,en;q=0.9', '-H',
      'content-type: application/json', '-H', 'origin: https://www.opera.com',
      '-H', 'referer: https://www.opera.com/', '-H',
      'sec-ch-ua: "Opera GX";v="105", "Chromium";v="119", "Not?A_Brand";v="24"',
      '-H', 'sec-ch-ua-mobile: ?0', '-H', 'sec-ch-ua-platform: "Windows"',
      '-H', 'sec-fetch-dest: empty', '-H', 'sec-fetch-mode: cors', '-H',
      'sec-fetch-site: cross-site', '-H',
      'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 OPR/105.0.0.0 (Edition std-1)',
      '--data-raw',
      '{"partnerUserId":"e518cd9e4d526d3de4aeb6d5e36f012bba82443ef1856a68029191ac8c6d136b"}',
      '--compressed'
  ]
  response = subprocess.run(curl_command, capture_output=True, text=True)

  # Parse the JSON response
  response_json = json.loads(response.stdout)

  # Get the token from the JSON response if it exists
  token = response_json.get("token")

  # Print the token if it exists
  if token:
    # Append the token to the text file
    URL = "https://discord.com/billing/partner-promotions/1180231712274387115" + token
    if OutputHTML == False:
      with open(output_txt_file, 'a') as f:
        f.write(URL + '\n\n')
    elif OutputHTML == True:
      index += 1
      with open(output_html_file, 'a') as f:
        f.write(f"{index}. <a href=\"{URL}\">{token}</a><br>\n\n")
    # Append the token to the list
    tokens.append(token)
print("please check for an output file")
if OutputHTML == True & HostHTML == True:
  # Host the HTML file as a web server on IP 0.0.0.0 and port 8080
  os.system(f"python -m http.server 8080 --bind 0.0.0.0")
原因分析
  1. curl跨平台行为差异:Windows默认未预装curl,手动安装后其输出格式、编码可能与Linux版本不同,比如输出带BOM的UTF-8文本或额外日志信息,导致response.stdout不符合标准JSON格式。
  2. subprocess编码不匹配:text=True在Windows下默认使用系统编码(如GBK),而API返回UTF-8编码内容,编码冲突会引发JSON解析失败。
  3. 命令执行失败:若curl不在Windows系统PATH中,subprocess.run会执行失败,此时response.stdout为空或包含错误信息,无法解析为JSON。
解决方案

方案一:修复curl调用(兼容现有逻辑)

  1. 确保Windows安装curl:从curl官方渠道下载并添加到系统PATH,或使用绝对路径调用curl。
  2. 统一编码格式:将subprocess.run的text=True替换为encoding='utf-8',强制使用UTF-8解析输出:
    response = subprocess.run(curl_command, capture_output=True, encoding='utf-8')
    
  3. 添加错误处理:在解析JSON前校验请求状态和响应内容,避免无效输入导致报错:
    if response.returncode != 0:
        print(f"curl执行错误: {response.stderr}")
        continue
    if not response.stdout.strip():
        print("空响应,跳过解析")
        continue
    try:
        response_json = json.loads(response.stdout)
    except json.JSONDecodeError as e:
        print(f"JSON解析失败: {e}, 响应内容: {response.stdout}")
        continue
    

方案二:替换为requests库(推荐,完全跨平台)

使用Python原生requests库发送HTTP请求,彻底摆脱对系统curl的依赖:

  1. 先安装依赖:pip install requests
  2. 修改请求逻辑:
    # 替换原有的subprocess和curl调用部分
    import requests
    
    # Loop the specified number of times
    for _ in range(num_loops):
        # 构造请求头和数据
        headers = {
            'authority': 'api.discord.gx.games',
            'accept': '*/*',
            'accept-language': 'en-US,en;q=0.9',
            'content-type': 'application/json',
            'origin': 'https://www.opera.com',
            'referer': 'https://www.opera.com/',
            'sec-ch-ua': '"Opera GX";v="105", "Chromium";v="119", "Not?A_Brand";v="24"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
            'sec-fetch-dest': 'empty',
            'sec-fetch-mode': 'cors',
            'sec-fetch-site': 'cross-site',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 OPR/105.0.0.0 (Edition std-1)',
        }
        data = '{"partnerUserId":"e518cd9e4d526d3de4aeb6d5e36f012bba82443ef1856a68029191ac8c6d136b"}'
        
        try:
            response = requests.post('https://api.discord.gx.games/v1/direct-fulfillment', headers=headers, data=data)
            response.raise_for_status()  # 检查HTTP请求是否成功
            response_json = response.json()
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
            continue
        except json.JSONDecodeError as e:
            print(f"JSON解析失败: {e}")
            continue
        
        # 后续获取token的逻辑保持不变
        token = response_json.get("token")
        # ... 剩余代码 ...
    
  3. 修复逻辑错误:将最后一行的OutputHTML == True & HostHTML == True改为OutputHTML and HostHTML(Python中逻辑与用and,&是位运算)。

额外优化

  • 避免文件写入乱码:打开TXT/HTML文件时指定encoding='utf-8':
    # TXT文件
    with open(output_txt_file, 'a', encoding='utf-8') as f:
        f.write(URL + '\n\n')
    # HTML文件
    with open(output_html_file, 'a', encoding='utf-8') as f:
        f.write(f"{index}. <a href=\"{URL}\">{token}</a><br>\n\n")
    

内容的提问来源于stack exchange,提问作者Gabrielzv1233

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:38:11