本地正常的Instagram下载Telegram Bot部署DigitalOcean后失效问题
Instagram下载Telegram Bot部署到DigitalOcean后失效问题
问题描述
本地VS Code运行时可正常下载Instagram Reels和帖子,但部署到DigitalOcean服务器后无法正常工作。已尝试更换IP地址、使用多个库,问题仍未解决。
相关代码
insta.py
import time import instaloader import requests from io import BytesIO def instagram_downloander(url, content_type): print(f"Content Type: {content_type}") try: ig = instaloader.Instaloader() shortcode = url.split('/')[-2] post = instaloader.Post.from_shortcode(ig.context, shortcode) for _ in range(3): try: post = instaloader.Post.from_shortcode(ig.context, shortcode) if post.is_video: video_url = post.video_url response = requests.get(video_url) if response.status_code == 200: return BytesIO(response.content), 'video' else: image_url = post.url response = requests.get(image_url) if response.status_code == 200: return BytesIO(response.content), 'image' except instaloader.exceptions.TooManyRequestsException: print("Rate limit reached. Retrying after delay...") time.sleep(600) except Exception as e: print(f"Retry failed: {e}") print("Unable to download the post. Please try later.") return None, None except instaloader.exceptions.BadResponseException as e: print(f"An error occurred while fetching post metadata: {e}") return None, None except Exception as e: print(f"Unexpected error: {e}") time.sleep(10) return instagram_downloander(url, content_type)
funct.py
elif user_state.get(user_id) == 'instagram_post': url = update.message.text content_type = 'post' await update.message.reply_text("Please wait 1 minute for loading...") media, media_type = instagram_downloander(url, content_type) if media and media_type: if media_type == 'video': await update.message.reply_video(video=media, filename='instagram_video.mp4') elif media_type == 'image': await update.message.reply_photo(photo=media, filename='instagram_image.jpg') else: await update.message.reply_text("Unsupported media type.") # Credit.deduct_credits(user_id, 1) await update.message.reply_text(f"🥳Download successful! \nFor using the bot again, please write /start.") else: await update.message.reply_text("Failed to download the Instagram content.") user_state[user_id] = None
故障原因及解决办法
1. Instagram对服务器IP的风控限制
DigitalOcean的数据中心IP段可能被Instagram标记为批量请求来源,即使更换同段IP也无法绕过拦截。
- 解决办法:
- 使用住宅代理IP替代数据中心IP,在instaloader和requests中配置代理:
# 给instaloader配置代理 from requests import Session session = Session() session.proxies = {"http": "http://your-residential-proxy:port", "https": "http://your-residential-proxy:port"} ig = instaloader.Instaloader(session=session) # 给requests请求配置代理 response = requests.get(video_url, proxies={"http": "http://your-residential-proxy:port", "https": "http://your-residential-proxy:port"}) - 为请求添加真实浏览器的User-Agent头,模拟正常用户访问:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } # 给requests添加headers response = requests.get(video_url, headers=headers) # 给instaloader添加headers ig.context._session.headers["User-Agent"] = headers["User-Agent"]
- 使用住宅代理IP替代数据中心IP,在instaloader和requests中配置代理:
2. 服务器网络端口/防火墙限制
DigitalOcean服务器的出站规则可能限制了HTTPS(443端口)访问,导致无法连接Instagram媒体资源域名。
- 解决办法:
- 检查服务器防火墙规则,确保允许出站访问443端口;
- 用
telnet scontent.cdninstagram.com 443测试连接,若无法连通,联系DigitalOcean客服确认网络限制。
3. Instaloader未登录导致权限不足
本地运行时可能缓存了Instagram登录会话,服务器无登录状态,无法访问部分受限内容(如私密账号帖子)。
- 解决办法:
- 在服务器上执行一次登录并保存会话:
ig = instaloader.Instaloader() ig.login("your-instagram-username", "your-instagram-password") ig.save_session_to_file("ig_session") - 后续代码中加载会话:
ig = instaloader.Instaloader() ig.load_session_from_file("your-instagram-username", "ig_session")
- 在服务器上执行一次登录并保存会话:
4. 依赖库版本不一致
本地与服务器的instaloader、requests版本差异可能引发兼容问题。
- 解决办法:
- 本地生成依赖清单:
pip freeze > requirements.txt; - 服务器安装相同版本依赖:
pip install -r requirements.txt。
- 本地生成依赖清单:
5. 服务器内存资源不足
服务器内存过小,导致下载媒体时内存溢出,无法生成BytesIO对象。
- 解决办法:
- 用
free -h查看内存使用,不足则升级服务器配置; - 改用临时文件存储媒体,避免内存过载:
import tempfile import os # 下载到临时文件 with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as f: f.write(response.content) temp_path = f.name # 发送文件后删除临时文件 await update.message.reply_video(video=open(temp_path, 'rb'), filename='instagram_video.mp4') os.unlink(temp_path)
- 用
调试建议
- 在服务器代码中增加详细日志,比如打印requests响应状态码、错误信息片段,定位是元数据获取失败还是媒体下载失败;
- 在服务器上直接运行测试脚本,手动传入Instagram链接,观察控制台输出的具体错误。
内容的提问来源于stack exchange,提问作者Rufat Shikhiyev
相关产品推荐
相关产品推荐

