Discord邮件机器人ImportError:无法导入imap_host求助
问题:导入imap_host时出现ImportError错误
本人无编程经验,为社团Discord服务器开发一款会议时间管理的邮件机器人,基于GitHub仓库RichardHladik/MailBot fork修改。运行main.py时出现ImportError: cannot import name 'imap_host'错误,修改导入语句无效,附上报错信息、代码和配置文件,请求技术帮助。
报错信息
PS C:\Users\jp518\OneDrive\Documents\vscode> & C:/Users/jp518/AppData/Local/Programs/Python/Python36/python.exe c:/Users/jp518/OneDrive/Documents/vscode/main.py Traceback (most recent call last): File "c:/Users/jp518/OneDrive/Documents/vscode/main.py", line 9, in <module> from config import ( ImportError: cannot import name 'imap_host'
main.py代码
# -*- coding: utf8 -*- import os import email import email.policy import discord import asyncio from aioimaplib import aioimaplib from selectolax.parser import HTMLParser from config import ( imap_host, user, passwd, mail_channel_id, token, ) intents = discord.Intents.default() client = discord.Client(intents=intents) imap_host = imap_host.split(":") def get_text_selectolax(html): """ parsing HTML from email and returning crucial parts as TEXT """ tree = HTMLParser(html) if tree.body is None: return None for tag in tree.css("script"): tag.decompose() for tag in tree.css("style"): tag.decompose() text = tree.body.text(separator="\n") return text def strip_ending(t, pattern): if t.endswith(pattern): t = t[: -len(pattern)] return t def simple_format(msg): msg = msg.replace("\n>\n", "\n> \n") msg = strip_ending(msg, "\n>") return msg async def chunkize(channel, msg): LIMIT = 2000 for i in range(0, len(msg), LIMIT): await channel.send(msg[i : i + LIMIT]) async def idle_loop(host, port, user, password): """ This will loop to get new emails and send them to "mail_channel_id" """ imap_client = aioimaplib.IMAP4_SSL(host=host, port=port, timeout=30) await imap_client.wait_hello_from_server() await imap_client.login(user, password) await imap_client.select() await asyncio.sleep(5) while True: # only get emails which we haven't read mail_channel = client.get_channel(mail_channel_id) status, data = await imap_client.search("(UNSEEN)") data = [d.decode() for d in data] for i in data[0].split(): print("Fetching msg {i}") typ, mail = await imap_client.fetch(str(i), "(RFC822)") mail_msg = email.message_from_bytes(mail[1], policy=email.policy.SMTP) mail_channel = client.get_channel(mail_channel_id) msg_header = ( f"**From:** {mail_msg['from']}\n" f"**Subject:** {mail_msg['subject']}\n" f"**To:** {mail_msg['to']}\n" f"**Date:** {mail_msg['date']}" ) msg_body = [] for part in mail_msg.walk(): if part.get_content_type() == "text/plain": message = "\n".join( part.get_payload(decode=True).decode().splitlines() ) message = get_text_selectolax(message).strip("\n") message = simple_format(message) msg_body.append(message) if part.get_content_maintype() == "multipart": continue if part.get("Content-Disposition") is None: continue msg = msg_header + "\n\n" + "\n".join(msg_body) await chunkize(mail_channel, msg) idle = await imap_client.idle_start(timeout=60) print((await imap_client.wait_server_push())) imap_client.idle_done() await asyncio.wait_for(idle, 30) @client.event async def on_ready(): print("We have logged in as {0.user}".format(client)) def on_error(event, *args, **kwargs): message, *_ = args print(message) os._exit(1) async def main(): async with client: client.loop.create_task( idle_loop(imap_host[0], int(imap_host[1]), user, passwd) ) client.loop.set_exception_handler(on_error) await client.start(token) asyncio.run(main())
config.py配置
imap_host = "imap.gmail.com:993" user = "redacted@gmail.com" passwd = "redacted" mail_channel_id = redacted token = "redacted"
解决方案
- 检查文件位置:确保
config.py和main.py在同一目录下,Python只会在当前运行目录和系统路径中查找模块,路径不对会导致无法导入。 - 修复config.py语法错误:
config.py里的mail_channel_id = redacted存在问题——如果redacted是数字(Discord频道ID是整数),直接写数字即可;如果是字符串形式,需要加引号。这行语法错误会导致整个config.py无法被Python正确加载,进而引发导入错误,这是最可能的原因。 - 验证变量拼写:确认
config.py里的变量名是imap_host,没有大小写错误或拼写失误。 - 测试基础导入:写一个简单的测试脚本
test.py,内容如下:
运行该脚本,看是否能成功输出from config import imap_host print(imap_host)imap_host的值,逐步排查问题。
内容的提问来源于stack exchange,提问作者jason Prescott
相关产品推荐
相关产品推荐

