如何修复Twitter API调用中的HTTP 403 Forbidden错误
问题:Python访问Twitter时出现HTTP Error 403: Forbidden
错误信息
File "C:\Users\HP\Lib\urllib\request.py", line 643, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden
原代码
import socket import ssl # Ignore SSL certificate errors ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mysock.connect(('www.twitter.com', 80)) cmd = 'GET https://twitter.com/bawo_nelson HTTP/1.0\r\n\r\n context=ctx'.encode() mysock.send(cmd) while True: data = mysock.recv(512) if len(data) < 1: break print(data.decode(),end='') mysock.close()
问题分析与解决方案
核心错误点
- 端口与协议不匹配:连接了HTTP的80端口,但请求的是HTTPS协议的URL,HTTPS必须使用443端口并完成SSL加密握手。
- 请求格式错误:
GET命令中混入了Python变量context=ctx,这不属于HTTP请求的一部分;同时缺少User-Agent等必要请求头,Twitter会拦截无标识的非浏览器请求。 - SSL上下文未正确使用:创建了SSL上下文,但没有用它包装socket,直接发送明文请求到80端口,无法建立HTTPS连接。
修正后的代码(基于socket+ssl)
import socket import ssl # 创建SSL上下文,建议保留证书验证,如需忽略可打开注释 ctx = ssl.create_default_context() # ctx.check_hostname = False # ctx.verify_mode = ssl.CERT_NONE # 连接Twitter的HTTPS端口443 mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sslsock = ctx.wrap_socket(mysock, server_hostname='twitter.com') sslsock.connect(('twitter.com', 443)) # 构造符合HTTP规范的请求,添加User-Agent标识 cmd = ( 'GET /bawo_nelson HTTP/1.1\r\n' 'Host: twitter.com\r\n' 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36\r\n' 'Connection: close\r\n\r\n' ).encode() sslsock.send(cmd) while True: data = sslsock.recv(512) if len(data) < 1: break print(data.decode(), end='') sslsock.close()
更简洁的方案(使用urllib.request)
手动处理socket容易出错,推荐用上层库:
import urllib.request import ssl # 可选:忽略证书错误(不建议生产环境使用) ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE # 构造请求,添加User-Agent避免被拦截 req = urllib.request.Request( 'https://twitter.com/bawo_nelson', headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} ) try: with urllib.request.urlopen(req, context=ctx) as response: html_content = response.read().decode() print(html_content) except urllib.error.HTTPError as e: print(f"请求失败:{e}")
额外提示
Twitter对非授权网页抓取的限制越来越严格,即使修正请求也可能被随时拦截。获取用户状态的合规方式是使用Twitter官方API,需要先申请开发者账号并获取API密钥。
内容的提问来源于stack exchange,提问作者Bawo Agbarajor
相关产品推荐
相关产品推荐

