import sys
import json
import sqlite3
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QSplitter, QListWidget,
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QLineEdit, QLabel, QMessageBox, QStatusBar)
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineProfile
from PyQt5.QtCore import QUrl, Qt, QTimer
from PyQt5.QtNetwork import QNetworkCookie
class AccountManager:
"""账号管理类,处理账号的存储和加载"""
def __init__(self, db_name='bilibili_accounts.db'):
self.conn = sqlite3.connect(db_name)
self.cursor = self.conn.cursor()
self._create_table()
def _create_table(self):
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
cookies TEXT NOT NULL
)
''')
self.conn.commit()
def add_account(self, name, cookies):
"""添加新账号"""
try:
self.cursor.execute(
"INSERT INTO accounts (name, cookies) VALUES (?, ?)",
(name, json.dumps(cookies))
)
self.conn.commit()
return True
except sqlite3.IntegrityError:
return False
def get_accounts(self):
"""获取所有账号"""
self.cursor.execute("SELECT id, name, cookies FROM accounts")
return [
{'id': row[0], 'name': row[1], 'cookies': json.loads(row[2])}
for row in self.cursor.fetchall()
]
def delete_account(self, account_id):
"""删除账号"""
self.cursor.execute("DELETE FROM accounts WHERE id=?", (account_id,))
self.conn.commit()
def __del__(self):
self.conn.close()
class BilibiliBrowser(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("B站多账号浏览器")
self.resize(1200, 800)
# 初始化账号管理器
self.account_manager = AccountManager()
# 创建UI
self.init_ui()
# 加载账号列表
self.load_accounts()
# 设置状态栏
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
self.status_bar.showMessage("就绪", 3000)
def init_ui(self):
"""初始化用户界面"""
# 主分割布局
main_splitter = QSplitter(Qt.Horizontal)
# 左侧账号管理区域
account_widget = QWidget()
account_layout = QVBoxLayout()
# 账号列表
account_layout.addWidget(QLabel("账号列表"))
self.account_list = QListWidget()
self.account_list.itemClicked.connect(self.switch_account)
account_layout.addWidget(self.account_list)
# 添加账号区域
add_account_layout = QHBoxLayout()
self.account_name_input = QLineEdit()
self.account_name_input.setPlaceholderText("输入账号名称")
add_account_layout.addWidget(self.account_name_input)
add_btn = QPushButton("添加账号")
add_btn.clicked.connect(self.add_account)
add_account_layout.addWidget(add_btn)
account_layout.addLayout(add_account_layout)
# 删除账号按钮
del_btn = QPushButton("删除选中账号")
del_btn.clicked.connect(self.delete_account)
account_layout.addWidget(del_btn)
# 检测账号状态按钮
check_btn = QPushButton("检测账号状态")
check_btn.clicked.connect(self.check_account_status)
account_layout.addWidget(check_btn)
account_widget.setLayout(account_layout)
# 右侧浏览器区域
browser_widget = QWidget()
browser_layout = QVBoxLayout()
# 导航栏
nav_layout = QHBoxLayout()
self.url_bar = QLineEdit()
self.url_bar.setPlaceholderText("输入网址或搜索内容")
self.url_bar.returnPressed.connect(self.navigate_to_url)
nav_layout.addWidget(self.url_bar)
home_btn = QPushButton("首页")
home_btn.clicked.connect(self.go_home)
nav_layout.addWidget(home_btn)
refresh_btn = QPushButton("刷新")
refresh_btn.clicked.connect(self.refresh_page)
nav_layout.addWidget(refresh_btn)
browser_layout.addLayout(nav_layout)
# 浏览器视图
self.browser = QWebEngineView()
self.browser.load(QUrl("https://www.bilibili.com"))
self.browser.urlChanged.connect(self.update_url_bar)
browser_layout.addWidget(self.browser)
browser_widget.setLayout(browser_layout)
# 添加组件到主分割器
main_splitter.addWidget(account_widget)
main_splitter.addWidget(browser_widget)
main_splitter.setSizes([300, 900])
self.setCentralWidget(main_splitter)
def load_accounts(self):
"""加载所有账号到列表"""
self.account_list.clear()
accounts = self.account_manager.get_accounts()
for account in accounts:
self.account_list.addItem(f"{account['name']} (ID:{account['id']})")
def add_account(self):
"""添加新账号"""
account_name = self.account_name_input.text().strip()
if not account_name:
QMessageBox.warning(self, "输入错误", "请输入账号名称")
return
# 获取当前浏览器的Cookie
cookie_store = self.browser.page().profile().cookieStore()
cookies = []
# 使用闭包捕获cookies列表
def capture_cookies(cookie):
print(cookie)
cookies.append({
'name': cookie.name().data().decode(),
'value': cookie.value().data().decode(),
'domain': cookie.domain(),
'path': cookie.path(),
'expirationDate': cookie.expirationDate().toSecsSinceEpoch() if cookie.expirationDate().isValid() else None
})
# 连接信号捕获Cookie
cookie_store.cookieAdded.connect(capture_cookies)
# 设置一个定时器来等待Cookie收集完成
QTimer.singleShot(1000, lambda: self.finalize_account_creation(account_name, cookies, cookie_store))
# 提示用户登录
self.browser.load(QUrl("https://passport.bilibili.com/login"))
self.status_bar.showMessage("请在浏览器中登录B站账号...", 5000)
def finalize_account_creation(self, account_name, cookies, cookie_store):
"""完成账号创建过程"""
# 断开信号连接
cookie_store.cookieAdded.disconnect()
print(cookies)
# 过滤B站相关Cookie
bili_cookies = [c for c in cookies if 'bilibili' in c['domain']]
print(bili_cookies)
if not bili_cookies:
QMessageBox.warning(self, "添加失败", "未检测到有效的B站Cookie")
return
# 保存账号
if self.account_manager.add_account(account_name, bili_cookies):
self.load_accounts()
self.account_name_input.clear()
self.status_bar.showMessage(f"账号 '{account_name}' 添加成功", 3000)
else:
QMessageBox.warning(self, "添加失败", "账号名称已存在")
def delete_account(self):
"""删除选中账号"""
current_item = self.account_list.currentItem()
if not current_item:
return
account_id = int(current_item.text().split("ID:")[1].strip(")"))
self.account_manager.delete_account(account_id)
self.load_accounts()
self.status_bar.showMessage("账号已删除", 3000)
def switch_account(self, item):
"""切换到选中的账号"""
account_id = int(item.text().split("ID:")[1].strip(")"))
accounts = self.account_manager.get_accounts()
account = next((a for a in accounts if a['id'] == account_id), None)
if account:
self.apply_cookies(account['cookies'])
self.browser.load(QUrl("https://www.bilibili.com"))
self.status_bar.showMessage(f"已切换到账号: {account['name']}", 3000)
def apply_cookies(self, cookies):
"""应用Cookie到浏览器"""
profile = QWebEngineProfile.defaultProfile()
cookie_store = profile.cookieStore()
cookie_store.deleteAllCookies() # 清除现有Cookie
for cookie_data in cookies:
cookie = QNetworkCookie()
cookie.setName(cookie_data['name'].encode())
cookie.setValue(cookie_data['value'].encode())
cookie.setDomain(cookie_data['domain'])
cookie.setPath(cookie_data['path'])
if cookie_data['expirationDate']:
cookie.setExpirationDate(cookie_data['expirationDate'])
cookie_store.setCookie(cookie)
def check_account_status(self):
"""检查选中账号的状态"""
current_item = self.account_list.currentItem()
if not current_item:
return
account_id = int(current_item.text().split("ID:")[1].strip(")"))
accounts = self.account_manager.get_accounts()
account = next((a for a in accounts if a['id'] == account_id), None)
if account:
# 使用requests验证Cookie有效性
session = requests.Session()
for cookie in account['cookies']:
session.cookies.set(
cookie['name'],
cookie['value'],
domain=cookie['domain'],
path=cookie['path']
)
try:
response = session.get("https://api.bilibili.com/x/web-interface/nav")
data = response.json()
if data['code'] == 0:
uname = data['data']['uname']
self.status_bar.showMessage(f"账号有效: {uname}", 5000)
else:
self.status_bar.showMessage("账号已失效,请重新登录", 5000)
except Exception as e:
self.status_bar.showMessage(f"检测失败: {str(e)}", 5000)
def navigate_to_url(self):
"""导航到输入的URL"""
url = self.url_bar.text().strip()
if not url.startswith(('http://', 'https://')):
url = 'https://' + url
self.browser.load(QUrl(url))
def update_url_bar(self, q):
"""更新URL地址栏"""
self.url_bar.setText(q.toString())
def go_home(self):
"""返回B站首页"""
self.browser.load(QUrl("https://www.bilibili.com"))
def refresh_page(self):
"""刷新当前页面"""
self.browser.reload()
if __name__ == "__main__":
app = QApplication(sys.argv)
browser = BilibiliBrowser()
browser.show()
sys.exit(app.exec_())
获取不到cookie请帮我检查修改并且完整返回
最新发布