You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python爬取iMessage?数据库路径错误问题求助

问题

我正在做一个远程控制Mac的项目,需要通过iPhone的Shortcuts功能向Mac发送指令,Mac用Python自动接收。要求用Shortcuts的「请求输入」动作简化操作,所以得用iMessage或iCloud邮件实现,避免在第三方应用手动输入(比如Discord的发送操作体验差)。

尝试用iMessage_reader库读取iMessage,但遇到以下问题:

  • 找不到官方文档里的chat.db,只找到chatRenderMetaData.db
  • 用这个文件运行脚本时报错:Error reading the database: no such table: message
  • 爬取iCloud邮件的方案也不可行,没找到可用的自动爬取脚本

解决思路

1. 修正iMessage数据库路径

Mac上iMessage的真实数据库路径是固定的,你之前找错了文件:

  • 正确路径:~/Library/Messages/chat.db(~/代表你的用户目录)
  • 注意:这个目录默认隐藏,按Command+Shift+.可以显示,或者直接用终端访问
  • 权限配置:需要给Python脚本/IDE开启「完全磁盘访问」权限(系统设置-隐私与安全性-完全磁盘访问)

修改后的可运行代码:

from imessage_reader import fetch_data

# 替换成你的用户名
DB_PATH = '/Users/你的用户名/Library/Messages/chat.db'

fd = fetch_data.FetchData(DB_PATH)
# 获取所有消息,可过滤最新的N条
my_data = fd.get_messages()
latest_messages = my_data[-5:]
print(latest_messages)

2. 改用HTTP直连方案(更可靠,无需爬取)

直接用Shortcuts发HTTP请求给Mac上的Python服务,比爬取数据库更高效:

第一步:Mac上运行Python HTTP服务

from flask import Flask, request
import subprocess

app = Flask(__name__)

@app.route('/remote-command', methods=['POST'])
def handle_command():
    command = request.form.get('cmd')
    print(f"收到指令:{command}")
    # 这里可以添加执行指令的逻辑,比如运行系统命令
    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return f"执行结果:\n{result.stdout}\n{result.stderr}"

if __name__ == '__main__':
    # 0.0.0.0允许局域网设备访问,端口可自定义
    app.run(host='0.0.0.0', port=5000, debug=True)

第二步:iPhone Shortcuts配置

  • 添加「请求输入」动作,让用户输入控制指令
  • 添加「发送HTTP请求」动作:
    • 方法选POST
    • URL填http://你的Mac局域网IP:5000/remote-command(Mac局域网IP可在「系统设置-网络」里查看)
    • 请求体选「表单」,添加键cmd,值选「请求输入」的结果

3. 备选:用Python标准库读取iCloud邮件

如果一定要用邮件方案,用Python自带的imaplib连接iCloud邮件服务器:

import imaplib
import email
from email.header import decode_header

# iCloud IMAP配置
IMAP_SERVER = 'imap.mail.me.com'
IMAP_PORT = 993
USERNAME = '你的iCloud邮箱@icloud.com'
# 必须用iCloud专用密码(Apple ID设置-安全-专用密码生成)
PASSWORD = '你的iCloud专用密码'

def fetch_new_emails():
    mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
    mail.login(USERNAME, PASSWORD)
    mail.select('INBOX')

    # 搜索未读邮件
    status, msg_ids = mail.search(None, 'UNSEEN')
    for msg_id in msg_ids[0].split():
        status, msg_data = mail.fetch(msg_id, '(RFC822)')
        msg = email.message_from_bytes(msg_data[0][1])
        
        # 解析主题
        subject, encode = decode_header(msg['Subject'])[0]
        if isinstance(subject, bytes):
            subject = subject.decode(encode)
        print(f"新邮件主题:{subject}")
        
        # 解析内容
        if msg.is_multipart():
            for part in msg.walk():
                if part.get_content_type() == 'text/plain':
                    body = part.get_payload(decode=True).decode()
                    print(f"邮件内容:{body}")
        else:
            body = msg.get_payload(decode=True).decode()
            print(f"邮件内容:{body}")
    
    mail.close()
    mail.logout()

fetch_new_emails()

内容的提问来源于stack exchange,提问作者NurseNeko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:07:35