遍历 Bookmarks.plist 中的所有书签

iterating over all the bookmarks in Bookmarks.plist

Bookmarks.plist 文件是 Safari 存储其书签的方式。我如何计算所有 URLString?

我可以通过以下方式获取书签文件:

BOOKMARKS_PLIST = '~/Library/Safari/Bookmarks.plist

将其从二进制转换为文本:

converted = subprocess.call(['plutil', '-convert', 'xml1', bookmarksFileCopy])

例如,访问单个条目:

'print plist['Children'][5]['Children'][1]['Children'][2]'

看来我应该使用递归遍历 'leaves of the tree' 但我无法在 python 中获得正确的语法。如您所知,我是初学者。

编辑: 谢谢何塞。虽然您的解决方案给出了我在下面描述的错误,但我确实让它起作用了:

import plistlib
import subprocess
import os

def countURLStrings(plistDict):
    childURLCounts = 0
    if 'Children' in plistDict.keys():
        for child in plistDict['Children']:
            childURLCounts += countURLStrings(child)
    if 'URLString' in plistDict.keys():
        childURLCounts += 1
        print plistDict.URLString
    return childURLCounts

BOOKMARKS_PLIST = '/Users/me/Desktop/Safari-20150403175048/Bookmarks.plist'
converted = subprocess.call(['plutil', '-convert', 'xml1', BOOKMARKS_PLIST])

pl = plistlib.readPlist(BOOKMARKS_PLIST)

ct = countURLStrings(pl)

print ct

作为奖励,这个迭代版本比我尝试但失败的递归更快。

第一个代码示例适用于 Python 3.4.2。 load()方法在2.x中不可用,readPlist()方法遇到错误。第二个代码示例使用 Python 2.7.6.

测试成功

BOOKMARKS_PLIST

  • 将 (BOOKMARKS_PLIST) 定义中的用户名替换为正确的用户名
  • 提供的方法 [countURLStrings(plistDict)] 递归地调用自己遇到的每个 'Children' 字典实例,并为每遇到一个 'URLString' 增加一个计数。

示例代码Python3.4.2

import plistlib

def countURLStrings(plistDict):
    childURLCounts = 0
    if 'Children' in plistDict.keys():
        for child in plistDict['Children']:
            childURLCounts += countURLStrings(child)
    if 'URLString' in plistDict.keys():
        childURLCounts += 1
    return childURLCounts

BOOKMARKS_PLIST = '/Users/username/Library/Safari/Bookmarks.plist'

with open(BOOKMARKS_PLIST, 'rb') as fp:
    pl = plistlib.load(fp)

countURLStrings(pl)

示例代码Python 2.7.6

import biplist

def countURLStrings(plistDict):
    childURLCounts = 0
    if 'Children' in plistDict.keys():
        for child in plistDict['Children']:
            childURLCounts += countURLStrings(child)
    if 'URLString' in plistDict.keys():
        childURLCounts += 1
    return childURLCounts

BOOKMARKS_PLIST = '/Users/jaburaschi/Library/Safari/Bookmarks.plist'

with open(BOOKMARKS_PLIST, 'rb') as fp:
    pl = biplist.readPlist(fp)

countURLStrings(pl)