plistlib 无法读取 Safari 的 plist 文件

4 投票
3 回答
4856 浏览
提问于 2025-04-17 21:01

我正在尝试用Python修改一个plist文件。我把一个plist文件从我的库里复制到了桌面上,这样可以安全地进行修改。我已经导入了 osplistlib 这两个模块。我在按照这里的文档进行操作。

import plistlib
import os

test_prefs = "~/Desktop/com.apple.Safari.plist"

x = readPlist(os.path.expanduser(test_prefs))
print x["TopSitesGridArrangement"]

但是这个操作失败了。我哪里做错了呢?

我遇到的具体错误是:

Traceback (most recent call last):
  File "/Users/Josh/Desktop/destroy.py", line 11, in <module>
    x = readPlist(os.path.expanduser(test_prefs))
NameError: name 'readPlist' is not defined

当我把代码改成 x = plistlib.readPlist(os.path.expanduser(test_prefs)) 时,我得到的错误如下(我的文件名叫 destroy.py):

Traceback (most recent call last):
  File "/Users/Josh/Desktop/destroy.py", line 11, in <module>
    x = plistlib.readPlist(os.path.expanduser(test_prefs))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plistlib.py", line 78, in readPlist
    rootObject = p.parse(pathOrFile)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plistlib.py", line 406, in parse
    parser.ParseFile(fileobj)
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 8

3 个回答

0

这一行代码:

import plistlib

创建了一个叫做 plistlib 的命名空间,所有的对象都存放在这里,这样可以避免和你自己定义的变量名冲突。

要使用 readPlist 这个函数,你需要用点号的方式来访问,也就是 plistlib.readPlist

x = plistlib.readPlist(os.path.expanduser(test_prefs))

另外,你也可以用这种语法把你需要的内容引入到全局空间:

from plistlib import readPlist, writePlist  # and anything else...
0

难道应该是 x = plistlib.readPlist(os.path.expanduser(test_prefs)) 吗?

13

问题在于,Safari的plist文件实际上是一个二进制格式的plist文件,而内置的plistlib无法读取这种格式。不过,你可以使用biplist来读取这些文件(需要先安装这个库):

>>> import biplist
>>> x = biplist.readPlist("com.apple.Safari.plist")
>>> x['LastOSVersionSafariWasLaunchedOn']
'10.9.1'

另外,你也可以使用plutil先把二进制plist格式转换成xml格式,然后再用plistlib来读取:

$ plutil -convert xml1 com.apple.Safari.plist
$ python
>>> import plistlib
>>> x = plistlib.readPlist("com.apple.Safari.plist")
>>> x['LastOSVersionSafariWasLaunchedOn']
'10.9.1'

撰写回答