Python实现Telegram频道图片自动下载:if条件不触发求助
Hey there, let's work through why your bot isn't picking up those channel photos. I've run into this exact problem with the latest python-telegram-bot versions, so here's what's going on and how to fix it:
1. The Core Problem: Photo is a List, Not a Single Object
First off, your current check if update.channel_post.photo: is on the right track, but you might not know that in the Telegram API (and thus python-telegram-bot), a photo post returns a list of PhotoSize objects (different resolutions of the same image), not a single photo object.
So even when a photo is posted, if you're expecting photo to be a single object with a file_id, that's why your condition might seem to fail (or you're trying to access file_id on the list itself, which would throw an error). Here's the corrected code:
# Check if the photo list isn't empty if update.channel_post.photo: # Grab the last element in the list (it's the highest-res version) highest_res_photo = update.channel_post.photo[-1] await context.bot.get_file(highest_res_photo.file_id).download()
(Note: If you're using the async version of python-telegram-bot (the standard now), you need to add await before get_file—your original sync syntax might be another issue if you're on v13+.)
2. Make Sure Your Bot Has the Right Permissions
This is a super common oversight:
- Your bot must be an admin of the target channel. Regular members can't read channel posts in most cases, especially if the channel is private.
- Double-check that the admin role has permission to read messages (it's enabled by default for admins, but it never hurts to confirm in the channel's admin settings).
3. Confirm You're Listening for Channel Post Updates
If you're using the newer Application setup (v13+), you need to explicitly tell your bot to listen for CHANNEL_POST updates. Here's a full minimal working example:
from telegram import Update from telegram.ext import ApplicationBuilder, MessageHandler, filters async def handle_channel_media(update: Update, context): # Log the post content to debug (optional but helpful) print(f"Received channel post: {update.channel_post}") # Handle photos if update.channel_post.photo: photo_file_id = update.channel_post.photo[-1].file_id await context.bot.get_file(photo_file_id).download("downloaded_photo.jpg") print("Photo downloaded successfully!") # Bonus: Handle image files sent as documents (if needed) elif update.channel_post.document and update.channel_post.document.mime_type.startswith('image/'): doc_file_id = update.channel_post.document.file_id await context.bot.get_file(doc_file_id).download("downloaded_image_doc.jpg") def main(): # Replace with your bot token app = ApplicationBuilder().token("YOUR_BOT_TOKEN").build() # Add a handler that listens specifically for channel posts app.add_handler(MessageHandler(filters.CHANNEL_POST, handle_channel_media)) app.run_polling() if __name__ == '__main__': main()
4. Debug to Rule Out Edge Cases
If it's still not working, add some debug prints to see what your bot is actually receiving:
- Print the full
update.channel_postobject to check ifphotoexists at all. - Sometimes, what looks like a photo might be sent as a
document(e.g., PNGs with metadata, or images sent as files). The example above includes a check for that case too.
内容的提问来源于stack exchange,提问作者Ali Asghari

