I'm trying to modify a plist file using python. I copied a plist from my library to my desktop to safely play with it. I've imported os
and plistlib
. I'm following what I see in the documentation here.
import plistlib
import os
test_prefs = "~/Desktop/com.apple.Safari.plist"
x = readPlist(os.path.expanduser(test_prefs))
print x["TopSitesGridArrangement"]
But this fails. What am I doing wrong?
The exact error I get:
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
When I change it to x = plistlib.readPlist(os.path.expanduser(test_prefs))
the errors I get are as follows (my file name is called 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
The issue is that Safari's plist file is actually a binary plist file format, which the built-in plistlib
can't read. However, biplist can read these files (requires installation):
>>> import biplist
>>> x = biplist.readPlist("com.apple.Safari.plist")
>>> x['LastOSVersionSafariWasLaunchedOn']
'10.9.1'
Alternatively, you can use plutil
to first convert the binary plist format to xml format, and then read it using plistlib
:
$ plutil -convert xml1 com.apple.Safari.plist
$ python
>>> import plistlib
>>> x = plistlib.readPlist("com.apple.Safari.plist")
>>> x['LastOSVersionSafariWasLaunchedOn']
'10.9.1'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With