chromium是chrome的开发版本,两个东西差不多。由于我们更加熟悉chrome浏览器。 下面我用chrome来代替chromium的发音。
chrome浏览器是一个非常前沿的东西,它和google搜索真的是解决了我们知识分享的一大难题。当然我们接触得更多的还是我们的度娘。
chrome很难实现的技术是不是太高深,其实也不全是,当然也不简单,我感觉它做得很好的地方,是它将所有的js数据分析为json结构,通过快速调用json解析来实现了浏览器的功能和页面渲染。
我突然想起想要获得我的历史记录,可惜chromium浏览器不能直接导出,于是我就找度娘,可惜度娘好像没得对相关技术的记录,但是我看到这个百度知道。我知道可能就是这个History文件就是我的目标了。
可是History是在哪个地方呢,我使用及其低端的手段,遍历了家目录下可能的文件,找可能的chromium的工作目录。
$ tree ./\.[a-z]* | grep chrom
找到~/.config/chromium目录,经过核实,确实是我们需要的工作目录。
最终找到History文件路径为
~/.config/chromium/Profile 1/History
一看这种没得后缀名的,可能是二进制文件,而非私有的二进制文件一般都会在文件头表明文件类型。于是我用bless工具打开二进制。
感谢大大,这里看大文件开头是SQLite format 3。 一看就知道正事来了。由于我有sql的经验,于是我简单了了下sqlite语法。
将History文件复制出来,通过下面命令:
$ cp '~/.config/chromium/Profile 1/History' ~/workspace/code/chrome_test/history/data
$ sqlite3 ~/workspace/chrome_test/history/data/History
sqlite> select * from sqlite_master;
得到下面的表格:
type | name | tbl_name | rootpage | sql |
---|---|---|---|---|
table | meta | meta | 2 | CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR) |
index | sqlite_autoindex_meta_1 | meta | 3 | |
table | urls | urls | 4 | CREATE TABLE urls(id INTEGER PRIMARY KEY AUTOINCREMENT,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL) |
table | sqlite_sequence | sqlite_sequence | 5 | CREATE TABLE sqlite_sequence(name,seq) |
table | visits | visits | 6 | CREATE TABLE visits(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit_time INTEGER NOT NULL,from_visit INTEGER,transition INTEGER DEFAULT 0 NOT NULL,segment_id INTEGER,visit_duration INTEGER DEFAULT 0 NOT NULL, incremented_omnibox_typed_score BOOLEAN DEFAULT FALSE NOT NULL) |
table | visit_source | visit_source | 7 | CREATE TABLE visit_source(id INTEGER PRIMARY KEY,source INTEGER NOT NULL) |
index | visits_url_index | visits | 8 | CREATE INDEX visits_url_index ON visits (url) |
index | visits_from_index | visits | 9 | CREATE INDEX visits_from_index ON visits (from_visit) |
index | visits_time_index | visits | 10 | CREATE INDEX visits_time_index ON visits (visit_time) |
table | keyword_search_terms | keyword_search_terms | 11 | CREATE TABLE keyword_search_terms (keyword_id INTEGER NOT NULL,url_id INTEGER NOT NULL,lower_term LONGVARCHAR NOT NULL,term LONGVARCHAR NOT NULL) |
table | downloads | downloads | 12 | CREATE TABLE downloads (id INTEGER PRIMARY KEY,guid VARCHAR NOT NULL,current_path LONGVARCHAR NOT NULL,target_path LONGVARCHAR NOT NULL,start_time INTEGER NOT NULL,received_bytes INTEGER NOT NULL,total_bytes INTEGER NOT NULL,state INTEGER NOT NULL,danger_type INTEGER NOT NULL,interrupt_reason INTEGER NOT NULL,hash BLOB NOT NULL,end_time INTEGER NOT NULL,opened INTEGER NOT NULL,last_access_time INTEGER NOT NULL,transient INTEGER NOT NULL,referrer VARCHAR NOT NULL,site_url VARCHAR NOT NULL,tab_url VARCHAR NOT NULL,tab_referrer_url VARCHAR NOT NULL,http_method VARCHAR NOT NULL,by_ext_id VARCHAR NOT NULL,by_ext_name VARCHAR NOT NULL,etag VARCHAR NOT NULL,last_modified VARCHAR NOT NULL,mime_type VARCHAR(255) NOT NULL,original_mime_type VARCHAR(255) NOT NULL) |
table | downloads_url_chains | downloads_url_chains | 13 | CREATE TABLE downloads_url_chains (id INTEGER NOT NULL,chain_index INTEGER NOT NULL,url LONGVARCHAR NOT NULL, PRIMARY KEY (id, chain_index) ) |
index | sqlite_autoindex_downloads_url_chains_1 | downloads_url_chains | 14 | |
table | downloads_slices | downloads_slices | 15 | CREATE TABLE downloads_slices (download_id INTEGER NOT NULL,offset INTEGER NOT NULL,received_bytes INTEGER NOT NULL, finished INTEGER NOT NULL DEFAULT 0,PRIMARY KEY (download_id, offset) ) |
index | sqlite_autoindex_downloads_slices_1 | downloads_slices | 16 | |
table | segments | segments | 17 | CREATE TABLE segments (id INTEGER PRIMARY KEY,name VARCHAR,url_id INTEGER NON NULL) |
index | segments_name | segments | 18 | CREATE INDEX segments_name ON segments(name) |
index | segments_url_id | segments | 19 | CREATE INDEX segments_url_id ON segments(url_id) |
table | segment_usage | segment_usage | 20 | CREATE TABLE segment_usage (id INTEGER PRIMARY KEY,segment_id INTEGER NOT NULL,time_slot INTEGER NOT NULL,visit_count INTEGER DEFAULT 0 NOT NULL) |
index | segment_usage_time_slot_segment_id | segment_usage | 21 | CREATE INDEX segment_usage_time_slot_segment_id ON segment_usage(time_slot, segment_id) |
index | segments_usage_seg_id | segment_usage | 22 | CREATE INDEX segments_usage_seg_id ON segment_usage(segment_id) |
table | typed_url_sync_metadata | typed_url_sync_metadata | 23 | CREATE TABLE typed_url_sync_metadata (storage_key INTEGER PRIMARY KEY NOT NULL,value BLOB) |
index | urls_url_index | urls | 24 | CREATE INDEX urls_url_index ON urls (url) |
index | keyword_search_terms_index1 | keyword_search_terms | 25 | CREATE INDEX keyword_search_terms_index1 ON keyword_search_terms (keyword_id, lower_term) |
index | keyword_search_terms_index2 | keyword_search_terms | 26 | CREATE INDEX keyword_search_terms_index2 ON keyword_search_terms (url_id) |
index | keyword_search_terms_index3 | keyword_search_terms | 27 | CREATE INDEX keyword_search_terms_index3 ON keyword_search_terms (term) |
table | sqlite_stat1 | sqlite_stat1 | 2977 | CREATE TABLE sqlite_stat1(tbl,idx,stat) |
第一列是数据类型,第二和第三列都是名字。有的数据类型需要,我们主要看table,两列都是一样的,就不去了解了,在这中间我们看到一个urls的表格。
sqlite> select * from urls;
id|url|title|visit_count|typed_count|last_visit_time|hidden
4|https://www.baidu.com/|百度一下,你就知道|996|261|13205907519338767|0
140|https://www.taobao.com/|淘宝网 - 淘!我喜欢|28|9|13205905606352979|0
然后密密麻麻三万多条记录就出来了,由于是比较隐私的,所以这里就放出来两条,给大家看看格式,下面是markdown格式后的:
id | url | title | visit_count | typed_count | last_visit_time | hidden |
---|---|---|---|---|---|---|
4 | https://www.baidu.com/ | 百度一下,你就知道 | 996 | 261 | 13205907519338767 | 0 |
140 | https://www.taobao.com/ | 淘宝网 - 淘!我喜欢 | 28 | 9 | 13205905606352979 | 0 |
感觉在表格看起要舒服些,下面我提供了一个python脚本,将urls的条目转换为csv文件,csv文件可以用wps表格打开,供大家学习。
import sqlite3
import csv
con = sqlite3.connect('data/History') # test.db3存在则直接读取,不存在则创建
cur = con.cursor() # 游标,可以认为类似于recordset
cur.execute('SELECT * FROM urls')
con.text_factory = str # sqlite默认为unicode输出,此处指定为str,即python默认的utf-8
header = ['id', 'url', 'title', 'visit_count',
'typed_count', 'last_visit_time', 'hidden']
csv_file = open('history.csv', 'w')
f_csv = csv.DictWriter(csv_file, header)
t = cur.fetchone()
while t is not None:
t_s = {}
for i, d in enumerate(t):
t_s[header[i]] = d
f_csv.writerow(t_s)
t = cur.fetchone()
csv_file.close()
cur.close()
con.close()
恩恩,为啥做这些了,这个事情大概就是心血来潮,想看看。
唉,今天点csdn的推送,报了一个华为比赛,头疼,有兴趣的小伙伴可以看看2019华为开发者大赛·IOT赛道-华为开发者大赛,csdn系统推送的地址。