浏览器历史记录

浏览器历史记录会以db后缀文件的形式,以明文存放在本地目录,用户可以通过解析这个文件查看浏览器最近访问,包括访问时间,网站图标等等。chrome内核的浏览器跟Firefox浏览器虽然都是保存在db文件中,但是数据结构完全不一样,需要做区分处理。

chrome浏览器

获取所有用户信息:

1
2
for user in wmi.WMI().Win32_UserAccount():
user_name = user.Name

这行代码使用 wmi 模块获取所有用户账户信息,并遍历这些信息,提取每个用户的用户名。

初始化 MD5 列表:

1
md5_list = []

这行代码创建了一个空列表,用于存储已经处理过的历史记录文件的 MD5 值,以避免重复处理。

获取每个用户的历史记录文件路径:

1
2
3
for path in self.get_path(user_name):
if os.path.isdir(path):
continue

这行代码调用 self.get_path(user_name) 方法获取指定用户的历史记录文件路径,并遍历这些路径。如果路径是一个目录,则跳过。

计算文件的 MD5 值:

1
2
3
4
5
md5_str = get_md5(path=path)
if md5_str in md5_list:
continue
else:
md5_list.append(md5_str)

这行代码计算文件的 MD5 值,并检查这个值是否已经在 md5_list 中。如果是,则跳过这个文件;如果不是,则将这个值添加到 md5_list 中。

复制文件并连接到数据库:

1
2
3
4
5
setting.log.info("正在处理: %s" % path)
tmp_path = path + ".backup"
shutil.copyfile(path, tmp_path)
conn = sqlite3.connect(tmp_path)
cur = conn.cursor()

这行代码将历史记录文件复制到一个临时文件,并连接到这个临时文件的 SQLite 数据库。

查询历史记录数据:

1
2
3
4
5
6
7
for time, url, title in cur.execute(
('SELECT visits.visit_time,urls.url, urls.title FROM urls, visits WHERE urls.id = visits.url')):
source_data = {
"Time": time,
"URL": url,
"Title": title
}

这行代码执行一个 SQL 查询,从数据库中获取历史记录的时间、URL 和标题,并将这些信息存储在 source_data 字典中。

处理数据并写入文件:

1
2
3
clean_data = get_line(self,source_data, self.display)
data = json.dumps(clean_data, ensure_ascii=False)
write_file(self.file,data)

这行代码调用 get_line 方法处理 source_data,并将处理后的数据转换为 JSON 格式,然后写入到输出文件中。

关闭数据库连接:

1
conn.close()

这行代码关闭数据库连接。

处理异常:

1
2
except Exception as e:
setting.log.error("处理失败, 原因: %s" % str(e))

这行代码捕获所有异常,并记录错误信息。

Firefox浏览器

获取所有用户信息:

1
2
for user in wmi.WMI().Win32_UserAccount():
user_name = user.Name

这行代码使用 wmi 模块获取所有用户账户信息,并遍历这些信息,提取每个用户的用户名。

初始化 MD5 列表:

1
md5_list = []

这行代码创建了一个空列表,用于存储已经处理过的历史记录文件的 MD5 值,以避免重复处理。

获取每个用户的历史记录文件路径:

1
2
3
for path in self.get_path(user_name):
if os.path.isdir(path):
continue

这行代码调用 self.get_path(user_name) 方法获取指定用户的历史记录文件路径,并遍历这些路径。如果路径是一个目录,则跳过。

计算文件的 MD5 值:

1
2
3
4
5
md5_str = get_md5(path=path)
if md5_str in md5_list:
continue
else:
md5_list.append(md5_str)

这行代码计算文件的 MD5 值,并检查这个值是否已经在 md5_list 中。如果是,则跳过这个文件;如果不是,则将这个值添加到 md5_list 中。

复制文件并连接到数据库:

1
2
3
4
5
setting.log.info("正在处理: %s" % path)
tmp_path = path + ".backup"
shutil.copyfile(path, tmp_path)
conn = sqlite3.connect(tmp_path)
cur = conn.cursor()

这行代码将历史记录文件复制到一个临时文件,并连接到这个临时文件的 SQLite 数据库。

查询历史记录数据:

1
2
3
4
5
6
7
for time, url, title in cur.execute(
('SELECT moz_historyvisits.visit_date, moz_places.url, moz_places.title FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id')):
source_data = {
"Time": time,
"URL": url,
"Title": title
}

这行代码执行一个 SQL 查询,从数据库中获取历史记录的时间、URL 和标题,并将这些信息存储在 source_data 字典中。

处理数据并写入文件:

1
2
3
clean_data = get_line(self,source_data, self.display)
data = json.dumps(clean_data, ensure_ascii=False)
write_file(self.file,data)

这行代码调用 get_line 方法处理 source_data,并将处理后的数据转换为 JSON 格式,然后写入到输出文件中。

关闭数据库连接:

1
conn.close()

这行代码关闭数据库连接。

处理异常:

1
2
except Exception as e:
setting.log.error("处理失败, 原因: %s" % str(e))

这行代码捕获所有异常,并记录错误信息。

引申

glob.glob(path, recursive=True)Pythonglob 模块的一个函数,用于根据指定的路径模式搜索文件和目录。这个函数的主要作用是匹配符合特定模式的文件路径,并返回一个列表,其中包含所有匹配的文件和目录的路径。

参数解释:

  • path: 一个字符串,表示要搜索的路径模式。这个模式可以包含通配符,如 *、? 和 [],用于匹配文件名或目录名的一部分。
  • recursive=True: 一个布尔值,表示是否递归搜索子目录。如果设置为 True,则函数会搜索指定目录及其所有子目录中的文件;如果设置为 False,则只搜索指定目录中的文件。

使用示例:

假设我们有一个目录结构如下:

1
2
3
4
5
6
C:\Users\username\Documents\
├── file1.txt
├── file2.txt
└── subfolder\
├── file3.txt
└── file4.txt

如果我们使用 glob.glob(path, recursive=True) 来搜索这个目录,其中 path"C:\\Users\\username\\Documents\\**\\*.txt",那么它将返回以下列表:

1
2
3
4
["C:\\Users\\username\\Documents\\file1.txt",
"C:\\Users\\username\\Documents\\file2.txt",
"C:\\Users\\username\\Documents\\subfolder\\file3.txt",
"C:\\Users\\username\\Documents\\subfolder\\file4.txt"]

这个列表包含了所有以 .txt 结尾的文件的路径,包括在子目录 subfolder 中的文件。

注意事项:

  • glob.glob 函数返回的路径是字符串形式,并且是绝对路径(如果 path 是绝对路径)或相对于当前工作目录的路径(如果 path 是相对路径)。
  • 如果 path 中的模式包含特殊字符,如 *、? 和 [],它们将被解释为通配符,用于匹配文件名或目录名的一部分。
  • 如果 recursive 参数设置为 True,则搜索是递归的,这可能会导致性能问题,特别是在处理大型目录结构时。

我的代码中,glob.glob(path, recursive=True) 用于在指定的用户目录下搜索所有包含 Chrome 关键字的目录,并查找其中名为 History 的文件。如果找到了这样的文件,它的路径将被添加到 files 列表中。