主要功能: - 完整的Flask-Admin后台管理系统 - 网站/标签/新闻管理功能 - 用户登录认证系统 - 科技感/未来风UI设计 - 标签分类系统(取代传统分类) - 详情页面展示 - 数据库迁移脚本 - 书签导入解析工具 技术栈: - Flask + SQLAlchemy - Flask-Admin管理界面 - Bootstrap 4响应式设计 - 用户认证与权限管理 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
146 lines
4.4 KiB
Python
146 lines
4.4 KiB
Python
"""测试批量导入功能的错误处理"""
|
|
import sys
|
|
import os
|
|
|
|
# 设置UTF-8编码
|
|
if sys.platform == 'win32':
|
|
import io
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
|
|
from utils.bookmark_parser import BookmarkParser
|
|
from utils.website_fetcher import WebsiteFetcher
|
|
|
|
def test_url_parsing():
|
|
"""测试URL列表解析"""
|
|
print("=" * 50)
|
|
print("测试1: URL列表解析")
|
|
print("=" * 50)
|
|
|
|
parser = BookmarkParser()
|
|
test_urls = """
|
|
https://www.google.com
|
|
https://github.com
|
|
https://invalid-url-that-does-not-exist-12345.com
|
|
http://example.com
|
|
# 这是注释,应该被忽略
|
|
https://www.python.org
|
|
"""
|
|
|
|
urls = parser.parse_url_list(test_urls)
|
|
print(f"成功解析 {len(urls)} 个URL:")
|
|
for idx, url_info in enumerate(urls, 1):
|
|
print(f" {idx}. {url_info['url']}")
|
|
print()
|
|
|
|
|
|
def test_website_fetching():
|
|
"""测试网站信息抓取"""
|
|
print("=" * 50)
|
|
print("测试2: 网站信息抓取(含错误处理)")
|
|
print("=" * 50)
|
|
|
|
fetcher = WebsiteFetcher(timeout=10)
|
|
|
|
test_cases = [
|
|
"https://www.google.com",
|
|
"https://github.com",
|
|
"https://invalid-url-that-does-not-exist-12345.com", # 这个应该失败
|
|
"https://httpbin.org",
|
|
]
|
|
|
|
for idx, url in enumerate(test_cases, 1):
|
|
print(f"\n[{idx}/{len(test_cases)}] 正在抓取: {url}")
|
|
try:
|
|
info = fetcher.fetch_website_info(url)
|
|
if info:
|
|
print(f" [OK] 成功:")
|
|
print(f" 名称: {info.get('name', 'N/A')[:50]}")
|
|
print(f" 描述: {info.get('description', 'N/A')[:80]}")
|
|
print(f" Logo: {info.get('logo_url', 'N/A')[:60]}")
|
|
else:
|
|
print(f" [FAIL] 失败: 无法获取网站信息")
|
|
except Exception as e:
|
|
print(f" [ERROR] 异常: {str(e)[:100]}")
|
|
print()
|
|
|
|
|
|
def test_error_isolation():
|
|
"""测试错误隔离 - 确保一个失败不影响其他"""
|
|
print("=" * 50)
|
|
print("测试3: 错误隔离验证")
|
|
print("=" * 50)
|
|
|
|
fetcher = WebsiteFetcher(timeout=5)
|
|
|
|
urls = [
|
|
{"url": "https://www.google.com", "name": "Google"},
|
|
{"url": "https://invalid-url-12345.com", "name": "Invalid"}, # 这个会失败
|
|
{"url": "https://github.com", "name": "GitHub"},
|
|
{"url": "https://another-invalid-url.xyz", "name": "Invalid2"}, # 这个也会失败
|
|
{"url": "https://www.python.org", "name": "Python"},
|
|
]
|
|
|
|
success_count = 0
|
|
failed_count = 0
|
|
|
|
for idx, item in enumerate(urls, 1):
|
|
url = item['url']
|
|
name = item['name']
|
|
|
|
print(f"\n[{idx}/{len(urls)}] 处理: {name} ({url})")
|
|
|
|
try:
|
|
# 模拟批量导入的错误处理逻辑
|
|
info = None
|
|
try:
|
|
info = fetcher.fetch_website_info(url)
|
|
except Exception as e:
|
|
print(f" ⚠ 抓取失败: {str(e)[:50]}")
|
|
|
|
if not info or not info.get('name'):
|
|
if name:
|
|
info = {'name': name, 'description': '', 'logo_url': ''}
|
|
print(f" [FALLBACK] 使用备用名称: {name}")
|
|
else:
|
|
failed_count += 1
|
|
print(f" [SKIP] 跳过: 无法获取信息且无备用名称")
|
|
continue
|
|
|
|
success_count += 1
|
|
print(f" [SUCCESS] 成功: {info.get('name', 'N/A')[:50]}")
|
|
|
|
except Exception as e:
|
|
failed_count += 1
|
|
print(f" [ERROR] 未知错误: {str(e)[:50]}")
|
|
continue # 继续处理下一个
|
|
|
|
print(f"\n{'=' * 50}")
|
|
print(f"测试完成:")
|
|
print(f" 总计: {len(urls)}")
|
|
print(f" 成功: {success_count}")
|
|
print(f" 失败: {failed_count}")
|
|
print(f" 成功率: {success_count / len(urls) * 100:.1f}%")
|
|
print(f"{'=' * 50}\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
test_url_parsing()
|
|
test_website_fetching()
|
|
test_error_isolation()
|
|
|
|
print("\n" + "=" * 50)
|
|
print("所有测试完成!")
|
|
print("=" * 50)
|
|
print("\n关键验证点:")
|
|
print("1. [OK] URL解析正常工作")
|
|
print("2. [OK] 网站信息抓取有错误处理")
|
|
print("3. [OK] 单个失败不影响其他URL处理")
|
|
print("4. [OK] 提供了备用方案(使用书签名称)")
|
|
|
|
except Exception as e:
|
|
print(f"\n测试过程中出现错误: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|