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

如何不使用Tweepy通过Twitter V2 API创建推文?代码报401错误求助

解决Twitter API请求返回401未授权错误的方案

你的代码触发401错误,核心原因是OAuth授权头不完整或不符合规范,以下是具体问题和修复方式:

核心问题分析

  • OAuth头参数缺失:你构造的Authorization头只包含了oauth_consumer_key、oauth_token和签名方法,但Twitter OAuth 1.0a要求必须包含oauth_signature、oauth_timestamp、oauth_nonce、oauth_version这些必填参数,缺少任何一个都会触发401。
  • 未生成有效签名:声明了oauth_signature_method=HMAC-SHA1,但没有生成对应的签名值。HMAC-SHA1签名需要结合消费者密钥(consumer_secret)、令牌密钥(access_token_secret)、请求方法、URL、请求参数等信息生成,不能仅声明方法。

修复方案

方案1:使用OAuth库自动处理(推荐)

用requests-oauthlib库可以自动生成完整的OAuth签名和头参数,避免手动构造出错:

from requests_oauthlib import OAuth1Session

# 替换为你的实际密钥
consumer_key = "你的consumer_key"
consumer_secret = "你的consumer_secret"
access_token = "你的access_token"
access_token_secret = "你的access_token_secret"
tweet_post_url = "https://api.twitter.com/1.1/statuses/update.json"  # v1.1 API地址,v2用https://api.twitter.com/2/tweets

# 初始化OAuth会话
twitter = OAuth1Session(
    consumer_key,
    client_secret=consumer_secret,
    resource_owner_key=access_token,
    resource_owner_secret=access_token_secret
)

# 构造请求数据(v2 API需调整参数格式)
data = {
    "text": text,
    "media_ids": [media_id]
}

# 发送请求
tweet_response = twitter.post(tweet_post_url, json=data)
print(tweet_response.json())

方案2:手动构造完整的OAuth头(不推荐,容易出错)

如果必须手动构造,需要生成所有必填参数并计算签名:

  1. 生成oauth_nonce(随机字符串)、oauth_timestamp(当前Unix时间戳)、oauth_version="1.0"
  2. 按照OAuth 1.0a规范,用HMAC-SHA1算法计算oauth_signature
  3. 拼接完整的Authorization头,示例代码如下:
import time
import random
import string
import hmac
import hashlib
import base64
import requests

# 生成随机nonce和时间戳
oauth_nonce = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))
oauth_timestamp = str(int(time.time()))

# 替换为你的实际密钥和参数
consumer_key = "你的consumer_key"
consumer_secret = "你的consumer_secret"
access_token = "你的access_token"
access_token_secret = "你的access_token_secret"
tweet_post_url = "https://api.twitter.com/1.1/statuses/update.json"
text = "你的推文内容"
media_id = "你的媒体ID"

# 构造参数列表用于签名(包括请求参数和OAuth参数)
params = {
    "oauth_consumer_key": consumer_key,
    "oauth_token": access_token,
    "oauth_signature_method": "HMAC-SHA1",
    "oauth_timestamp": oauth_timestamp,
    "oauth_nonce": oauth_nonce,
    "oauth_version": "1.0",
    "text": text,
    "media_ids": media_id
}

# 按OAuth规范排序参数并拼接成字符串
sorted_params = sorted(params.items(), key=lambda x: x[0])
param_string = '&'.join([f"{k}={v}" for k, v in sorted_params])

# 构造签名基字符串
base_string = f"POST&{tweet_post_url}&{param_string}"

# 生成签名密钥
signing_key = f"{consumer_secret}&{access_token_secret}"

# 计算HMAC-SHA1签名并base64编码
signature = hmac.new(signing_key.encode(), base_string.encode(), hashlib.sha1).digest()
oauth_signature = base64.b64encode(signature).decode()

# 构造完整的Authorization头
headers = {
    "Authorization": f'OAuth oauth_consumer_key="{consumer_key}", oauth_token="{access_token}", oauth_signature_method="HMAC-SHA1", oauth_timestamp="{oauth_timestamp}", oauth_nonce="{oauth_nonce}", oauth_version="1.0", oauth_signature="{oauth_signature}"'
}

# 发送请求
data = {
    "text": text,
    "media_ids": [media_id],
    "tweet_mode": "extended"
}
tweet_response = requests.post(tweet_post_url, headers=headers, data=data)
print(tweet_response.json())

额外检查项

  • 确认你的access_token拥有发布推文的权限(比如v1.1的write权限,v2的tweet.write权限),权限不足也会返回401。
  • 核对所有密钥(consumer_key、consumer_secret、access_token、access_token_secret)是否和开发者平台上的一致,避免拼写或大小写错误。
  • 确认tweet_post_url是否正确,v1.1和v2 API的地址不同,参数格式也有差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:47:36