
Pyrogram 的 MessageEntityType 是一个枚举类,需通过 MessageEntityType.PHONE_NUMBER 枚举成员而非字符串进行类型比对,并结合 offset 和 length 截取原始文本中的手机号段。
pyrogram 的 `messageentitytype` 是一个枚举类,需通过 `messageentitytype.phone_number` 枚举成员而非字符串进行类型比对,并结合 `offset` 和 `length` 截取原始文本中的手机号段。
在使用 Pyrogram 解析 Telegram 消息实体时,初学者常误将枚举值与字符串字面量直接比较(如 entity.type == 'MessageEntityType.PHONE_NUMBER'),这会导致条件始终为 False,无法命中手机号实体。根本原因在于:entity.type 是 pyrogram.enums.MessageEntityType 枚举的一个实例(例如 <messageentitytype.phone_number:></messageentitytype.phone_number:>),而非字符串。
✅ 正确做法是:
-
显式导入枚举类:
from pyrogram.enums import MessageEntityType
-
用枚举成员做等值判断:
if entity.type == MessageEntityType.PHONE_NUMBER:
-
精准提取手机号文本:
Telegram 不会自动存储号码内容,而是通过offset(起始位置)和length(字符长度)标注其在message.text中的范围,因此需手动切片:phone = message.text[entity.offset : entity.offset + entity.length] print(phone)
完整可运行示例:
from pyrogram import Client
from pyrogram.enums import MessageEntityType
app = Client("my_account")
def main():
group_url = "your_group_username_or_id" # e.g., "@pyrogramchat"
with app:
messages = app.get_chat_history(group_url, limit=100)
for message in messages:
if message.text and message.entities:
for entity in message.entities:
if entity.type == MessageEntityType.PHONE_NUMBER:
# 安全截取:防止 offset/length 越界(虽极少发生,但建议防御)
start = max(0, entity.offset)
end = min(len(message.text), start + entity.length)
phone = message.text[start:end].strip()
if phone: # 过滤空结果
print(f"Found phone: {phone}")
if __name__ == "__main__":
main()
⚠️ 注意事项:
-
message.text可能为None(如纯媒体消息),务必先校验; -
entity.offset和entity.length基于 UTF-16 编码偏移(Telegram 协议要求),但 Pyrogram 已自动适配 Python 字符串索引,可直接使用; - 同一消息可能含多个实体(如 URL + PHONE_NUMBER),需遍历全部
message.entities; - 手机号格式未标准化(可能含
+,-, 空格等),如需清洗,建议后续用正则(如re.sub(r'[^0-9+]', '', phone))。
掌握枚举的正确使用方式,是深入理解 Pyrogram 消息解析机制的关键一步——它不仅适用于 PHONE_NUMBER,同样适用于 URL、MENTION、HASHTAG 等所有实体类型。










