import webbrowser
import os
import json
import urllib.request
import random
from datetime import datetime
def fetch_hot_searches():
"""获取热门搜索词(最多55个)"""
try:
# 从百度风云榜获取热门搜索
url = "https://top.baidu.com/board?platform=pc"
with urllib.request.urlopen(url, timeout=3) as response:
html = response.read().decode('utf-8')
# 解析HTML获取热搜数据
start_index = html.find('<!--s-data:')
if start_index != -1:
end_index = html.find('-->', start_index)
json_str = html[start_index+11:end_index].strip()
data = json.loads(json_str)
# 提取所有热搜词(最多55个)
all_hot_searches = []
for card in data['data']['cards']:
for item in card['content']:
all_hot_searches.append(item['word'])
if len(all_hot_searches) >= 55:
break
if len(all_hot_searches) >= 55:
break
return all_hot_searches
except Exception as e:
print(f"获取热门搜索失败: {e}")
# 备用热门搜索词
return [
"深度学习", "人工智能", "机器学习", "神经网络",
"Python编程", "数据科学", "自然语言处理",
"计算机视觉", "TensorFlow", "PyTorch",
"前端框架", "后端开发", "数据库优化", "算法竞赛",
"云计算", "大数据", "区块链", "物联网",
"网络安全", "DevOps", "微服务", "容器技术",
"React", "Vue.js", "Angular", "Node.js",
"Java", "C++", "Go语言", "Rust",
"Swift", "Kotlin", "TypeScript", "Docker",
"Kubernetes", "Git", "Linux", "Windows",
"MacOS", "iOS开发", "Android开发", "Flutter",
"Unity", "游戏开发", "AR/VR", "5G技术",
"量子计算", "边缘计算", "自动驾驶", "机器人技术",
"芯片技术", "半导体", "元宇宙", "Web3.0"
]
def generate_search_page():
"""生成带AI搜索功能和多引擎搜索的HTML页面,包含历史记录和热门搜索"""
# 获取热门搜索词(最多55个)
all_hot_searches = fetch_hot_searches()
# 如果不足55个,补充到55个
if len(all_hot_searches) < 55:
backup_searches = [
"深度学习", "人工智能", "机器学习", "神经网络",
"Python编程", "数据科学", "自然语言处理",
"计算机视觉", "TensorFlow", "PyTorch"
]
while len(all_hot_searches) < 55:
all_hot_searches.append(random.choice(backup_searches))
# 随机选择10个热搜词用于初始显示
initial_hot_searches = random.sample(all_hot_searches, 10)
html_content = f'''
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>智能搜索平台</title>
<style>
* {{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}}
body {{
background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
min-height: 100vh;
padding: 20px;
}}
.container {{
max-width: 800px;
margin: 0 auto;
padding: 30px;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
animation: fadeIn 0.8s ease-out;
}}
@keyframes fadeIn {{
0% {{ opacity: 0; transform: translateY(-20px); }}
100% {{ opacity: 1; transform: translateY(0); }}
}}
.logo {{
text-align: center;
margin-bottom: 30px;
}}
.logo img {{
height: 60px;
transition: transform 0.3s;
}}
.logo img:hover {{
transform: scale(1.05);
}}
.search-engine {{
display: flex;
justify-content: center;
margin-bottom: 20px;
flex-wrap: wrap;
}}
.engine-btn {{
margin: 5px;
padding: 8px 15px;
border: none;
border-radius: 20px;
background: #e9ecef;
cursor: pointer;
transition: all 0.3s;
font-size: 14px;
}}
.engine-btn.active, .engine-btn:hover {{
background: #1a73e8;
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}}
.search-box {{
display: flex;
margin-bottom: 30px;
border-radius: 50px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s;
}}
.search-box:focus-within {{
box-shadow: 0 5px 20px rgba(26, 115, 232, 0.3);
}}
.search-input {{
flex: 1;
padding: 15px 25px;
border: none;
font-size: 16px;
outline: none;
background: #f8f9fa;
transition: background 0.3s;
}}
.search-input:focus {{
background: #fff;
}}
.search-btn {{
padding: 15px 30px;
border: none;
background: #1a73e8;
color: white;
font-weight: bold;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}}
.search-btn:hover {{
background: #0d5cb6;
transform: scale(1.02);
}}
.hot-searches {{
margin-bottom: 30px;
position: relative;
}}
.section-title {{
font-size: 18px;
margin-bottom: 15px;
color: #333;
padding-bottom: 8px;
border-bottom: 2px solid #1a73e8;
display: flex;
align-items: center;
}}
.section-title::before {{
content: "🔥";
margin-right: 8px;
}}
.hot-tags {{
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 15px;
}}
.hot-tag {{
padding: 8px 15px;
background: #e9f5ff;
border-radius: 20px;
color: #1a73e8;
cursor: pointer;
transition: all 0.3s;
font-size: 14px;
position: relative;
overflow: hidden;
}}
.hot-tag::before {{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent);
transform: translateX(-100%);
transition: transform 0.5s;
}}
.hot-tag:hover {{
background: #1a73e8;
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}}
.hot-tag:hover::before {{
transform: translateX(100%);
}}
.hot-tag.hot {{
background: #fff0f0;
color: #e74c3c;
}}
.hot-tag.new {{
background: #e8f5e9;
color: #27ae60;
}}
.refresh-btn {{
position: absolute;
top: 5px;
right: 0;
padding: 5px 15px;
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 15px;
cursor: pointer;
transition: all 0.3s;
font-size: 13px;
display: flex;
align-items: center;
}}
.refresh-btn:hover {{
background: #e9ecef;
transform: scale(1.05);
}}
.refresh-btn::before {{
content: "🔄";
margin-right: 5px;
}}
.hidden-data {{
display: none;
}}
</style>
</head>
<body>
<div class="container">
<div class="logo">
<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" alt="百度搜索">
</div>
<div class="search-engine">
<button class="engine-btn active" data-engine="baidu">百度</button>
<button class="engine-btn" data-engine="google">谷歌</button>
<button class="engine-btn" data-engine="bing">必应</button>
<button class="engine-btn" data-engine="ai">AI搜索</button>
</div>
<div class="search-box">
<input type="text" class="search-input" id="searchInput" placeholder="请输入搜索内容...">
<button class="search-btn" id="searchBtn">百度一下</button>
</div>
<div class="hot-searches">
<h3 class="section-title">实时热搜榜</h3>
<button class="refresh-btn" id="refreshHot">换一换</button>
<div class="hot-tags" id="hotTagsContainer">
{"".join(
[f'<div class="hot-tag {"" if i < 3 else "hot" if i < 6 else "new"}" data-keyword="{tag}">{tag}</div>'
for i, tag in enumerate(initial_hot_searches)]
)}
</div>
</div>
<!-- 存储所有热搜词(隐藏) -->
<div class="hidden-data" id="allHotSearches">{json.dumps(all_hot_searches)}</div>
<div class="search-history">
<h3 class="section-title">搜索历史</h3>
<div class="history-list" id="historyList"></div>
<button class="clear-history" id="clearHistory">清除历史</button>
</div>
</div>
<script>
// 搜索引擎配置
const engines = {{
baidu: "https://www.baidu.com/s?wd=",
google: "https://www.google.com/search?q=",
bing: "https://www.bing.com/search?q=",
ai: "https://www.baidu.com/s?wd=AI+" // AI搜索前缀
}};
let currentEngine = "baidu";
const HISTORY_KEY = "searchHistory";
// DOM元素
const searchInput = document.getElementById("searchInput");
const searchBtn = document.getElementById("searchBtn");
const engineBtns = document.querySelectorAll(".engine-btn");
const hotTagsContainer = document.getElementById("hotTagsContainer");
const refreshHotBtn = document.getElementById("refreshHot");
const historyList = document.getElementById("historyList");
const clearHistoryBtn = document.getElementById("clearHistory");
const allHotSearches = JSON.parse(document.getElementById("allHotSearches").textContent);
// 初始化页面
document.addEventListener("DOMContentLoaded", () => {{
loadSearchHistory();
updateSearchButton();
// 设置引擎按钮事件
engineBtns.forEach(btn => {{
btn.addEventListener("click", () => {{
engineBtns.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
currentEngine = btn.dataset.engine;
updateSearchButton();
}});
}});
// 搜索按钮事件
searchBtn.addEventListener("click", performSearch);
// 回车键搜索
searchInput.addEventListener("keyup", (e) => {{
if (e.key === "Enter") {{
performSearch();
}}
}});
// 换一换按钮事件
refreshHotBtn.addEventListener("click", refreshHotSearches);
// 清除历史按钮事件
clearHistoryBtn.addEventListener("click", clearSearchHistory);
// 聚焦搜索框
searchInput.focus();
}});
// 更新搜索按钮文字
function updateSearchButton() {{
const engineNames = {{
baidu: "百度一下",
google: "Google搜索",
bing: "必应搜索",
ai: "AI搜索"
}};
searchBtn.textContent = engineNames[currentEngine];
}}
// 执行搜索
function performSearch() {{
const keyword = searchInput.value.trim();
if (!keyword) {{
searchInput.focus();
return;
}}
// 保存搜索历史
saveSearchHistory(keyword);
// 构建搜索URL
let searchUrl = engines[currentEngine] + encodeURIComponent(keyword);
// 特殊处理AI搜索
if (currentEngine === "ai") {{
searchUrl += "&t=ai";
}}
// 打开新标签页
window.open(searchUrl, "_blank");
}}
// 刷新热搜词
function refreshHotSearches() {{
// 随机选择10个不重复的热搜词
const shuffled = [...allHotSearches].sort(() => 0.5 - Math.random());
const selected = shuffled.slice(0, 10);
// 清空容器
hotTagsContainer.innerHTML = '';
// 添加新的热搜标签
selected.forEach((tag, index) => {{
const tagClass = index < 3 ? "" : index < 6 ? "hot" : "new";
const tagElement = document.createElement('div');
tagElement.className = `hot-tag ${{tagClass}}`;
tagElement.dataset.keyword = tag;
tagElement.textContent = tag;
// 添加点击事件
tagElement.addEventListener('click', () => {{
searchInput.value = tag;
performSearch();
}});
hotTagsContainer.appendChild(tagElement);
}});
// 添加轻微动画效果
hotTagsContainer.style.opacity = '0';
setTimeout(() => {{
hotTagsContainer.style.transition = 'opacity 0.3s ease-in-out';
hotTagsContainer.style.opacity = '1';
}}, 10);
}}
// 保存搜索历史
function saveSearchHistory(keyword) {{
let history = JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]');
// 移除重复项
history = history.filter(item => item.keyword !== keyword);
// 添加新记录
history.unshift({{
keyword: keyword,
timestamp: new Date().toISOString()
}});
// 最多保留10条记录
if (history.length > 10) {{
history = history.slice(0, 10);
}}
localStorage.setItem(HISTORY_KEY, JSON.stringify(history));
loadSearchHistory();
}}
// 加载搜索历史
function loadSearchHistory() {{
const history = JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]');
historyList.innerHTML = '';
history.forEach(item => {{
const historyItem = document.createElement('div');
historyItem.className = 'history-item';
historyItem.textContent = item.keyword;
historyItem.addEventListener('click', () => {{
searchInput.value = item.keyword;
performSearch();
}});
historyList.appendChild(historyItem);
}});
}}
// 清除搜索历史
function clearSearchHistory() {{
localStorage.removeItem(HISTORY_KEY);
loadSearchHistory();
}}
</script>
</body>
</html>
'''
# 保存为HTML文件
file_path = os.path.abspath('smart_search_engine.html')
with open(file_path, 'w', encoding='utf-8') as f:
f.write(html_content)
# 自动在浏览器中打开
webbrowser.open(f'file://{file_path}')
return f"已生成智能搜索页面: {file_path}"
# 生成并打开页面
if __name__ == "__main__":
result = generate_search_page()
print(result)
去掉搜索历史