You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQLite中的Brave浏览器历史数据发送至服务器并实现账户管理

家长监控系统实现指导

一、Ubuntu Server端搭建方案

1. 技术栈选择

用轻量的Flask框架快速搭建后端,搭配SQLite存储数据,JWT做身份认证。先安装依赖:

sudo apt update && sudo apt install python3-pip
pip3 install flask flask-sqlalchemy flask-jwt-extended requests

2. 数据库表设计

创建两个核心表:

  • 用户表(users):存储家长/孩子账户信息
    • 字段:id(主键)、username(唯一)、password_hash(加密密码)、role(parent/child)、parent_id(孩子关联的家长ID,可为空)
  • 浏览历史表(browser_history):存储孩子的上网记录
    • 字段:id(主键)、child_id(关联用户表孩子ID)、url、title、visit_time、created_at(上传时间)

3. 核心API接口实现

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from werkzeug.security import generate_password_hash, check_password_hash
import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///monitor.db'
app.config['JWT_SECRET_KEY'] = 'your-random-secret-key'  # 替换为随机生成的密钥
db = SQLAlchemy(app)
jwt = JWTManager(app)

# 模型定义
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(120), nullable=False)
    role = db.Column(db.String(20), nullable=False)
    parent_id = db.Column(db.Integer, db.ForeignKey('user.id'))

class BrowserHistory(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    child_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    url = db.Column(db.String(500), nullable=False)
    title = db.Column(db.String(500))
    visit_time = db.Column(db.DateTime, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)

# 注册接口
@app.route('/api/register', methods=['POST'])
def register():
    data = request.get_json()
    if User.query.filter_by(username=data['username']).first():
        return jsonify({'msg': '用户名已存在'}), 400
    password_hash = generate_password_hash(data['password'])
    new_user = User(
        username=data['username'],
        password_hash=password_hash,
        role=data['role'],
        parent_id=data.get('parent_id')
    )
    db.session.add(new_user)
    db.session.commit()
    return jsonify({'msg': '注册成功'}), 201

# 登录接口
@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    user = User.query.filter_by(username=data['username']).first()
    if not user or not check_password_hash(user.password_hash, data['password']):
        return jsonify({'msg': '用户名或密码错误'}), 401
    access_token = create_access_token(identity={'id': user.id, 'role': user.role})
    return jsonify(access_token=access_token), 200

# 上传浏览历史接口
@app.route('/api/history/upload', methods=['POST'])
@jwt_required()
def upload_history():
    current_user = get_jwt_identity()
    if current_user['role'] != 'child':
        return jsonify({'msg': '仅孩子账户可上传数据'}), 403
    data = request.get_json()
    for item in data['history']:
        history_item = BrowserHistory(
            child_id=current_user['id'],
            url=item['url'],
            title=item['title'],
            visit_time=datetime.datetime.fromisoformat(item['visit_time'])
        )
        db.session.add(history_item)
    db.session.commit()
    return jsonify({'msg': '数据上传成功'}), 200

# 获取孩子历史数据接口(家长用)
@app.route('/api/history/get', methods=['GET'])
@jwt_required()
def get_history():
    current_user = get_jwt_identity()
    if current_user['role'] != 'parent':
        return jsonify({'msg': '仅家长账户可查看数据'}), 403
    child_id = request.args.get('child_id')
    # 验证孩子是否属于当前家长
    child = User.query.filter_by(id=child_id, parent_id=current_user['id']).first()
    if not child:
        return jsonify({'msg': '无权访问该孩子数据'}), 403
    history = BrowserHistory.query.filter_by(child_id=child_id).order_by(BrowserHistory.visit_time.desc()).all()
    result = [{
        'url': item.url,
        'title': item.title,
        'visit_time': item.visit_time.isoformat()
    } for item in history]
    return jsonify(history=result), 200

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(host='0.0.0.0', port=5000)

二、客户端代码修改(发送数据到服务器)

修改你的Brave历史读取脚本,替换打印逻辑为上传数据:

import sqlite3
import os
import requests
import json
from datetime import datetime

# 服务器配置
SERVER_URL = "http://你的Ubuntu服务器IP:5000"
CHILD_USERNAME = "孩子账户用户名"
CHILD_PASSWORD = "孩子账户密码"

def get_access_token():
    """获取JWT认证token"""
    login_data = {
        "username": CHILD_USERNAME,
        "password": CHILD_PASSWORD
    }
    try:
        response = requests.post(f"{SERVER_URL}/api/login", json=login_data)
        response.raise_for_status()
        return response.json()['access_token']
    except Exception as e:
        print(f"登录失败: {str(e)}")
        return None

def upload_history(history_data, token):
    """上传浏览历史到服务器"""
    headers = {"Authorization": f"Bearer {token}"}
    payload = {"history": history_data}
    try:
        response = requests.post(f"{SERVER_URL}/api/history/upload", json=payload, headers=headers)
        response.raise_for_status()
        print("数据上传成功")
    except Exception as e:
        print(f"上传失败: {str(e)}")

def main():
    try:
        # 获取Brave历史路径(适配macOS,Windows/Linux需调整路径)
        home_dir = os.path.expanduser("~")
        history_path = os.path.join(home_dir, "Library/Application Support/BraveSoftware/Brave-Browser/Default/History")
        
        if not os.path.isfile(history_path):
            raise FileNotFoundError(f"Brave History文件未找到: {history_path}")
        
        # 连接数据库并查询历史
        con = sqlite3.connect(history_path)
        con.row_factory = sqlite3.Row  # 让查询结果可通过字段名访问
        cur = con.cursor()
        
        # 查询最近的50条记录(可按需调整数量)
        cur.execute("SELECT url, title, last_visit_time FROM urls ORDER BY last_visit_time DESC LIMIT 50")
        history_data = []
        for row in cur.fetchall():
            # 转换时间格式:Brave的last_visit_time是微秒级时间戳
            visit_time = datetime.fromtimestamp(row['last_visit_time'] / 1_000_000)
            history_data.append({
                "url": row['url'],
                "title": row['title'],
                "visit_time": visit_time.isoformat()
            })
        
        con.close()
        
        # 获取token并上传数据
        token = get_access_token()
        if token:
            upload_history(history_data, token)
    
    except sqlite3.Error as e:
        print(f"SQLite错误: {str(e)}")
    except Exception as e:
        print(f"错误: {str(e)}")

if __name__ == "__main__":
    main()

客户端注意事项

  • 不同系统的Brave历史路径不同:
    • Windows: C:\Users\{用户名}\AppData\Local\BraveSoftware\Brave-Browser\User Data\Default\History
    • Linux: ~/.config/BraveSoftware/Brave-Browser/Default/History
  • 建议把脚本设为定时任务(比如用crontab),定期自动上传数据

三、账户关联与数据展示逻辑

  1. 账户创建流程:
    • 先注册家长账户:调用/api/register,role设为parent
    • 再注册孩子账户:调用/api/register,role设为child,并填写parent_id为对应家长的ID
  2. 数据展示:
    • 移动端应用通过家长账户登录获取token
    • 调用/api/history/get接口,传入要查看的孩子ID,获取该孩子的浏览历史
    • 前端可按时间排序、关键词搜索、统计访问频率等方式展示数据

内容的提问来源于stack exchange,提问作者Lardsonian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:45:17