用AI写的【实时文件搜索引擎】python源码【找资源】

我想实现一个实时文件搜索网页,输入要搜索的文件关键字,后台不断爬取文件,并同时边把爬取的文件实时展示在网页上,比如"视频",就会把所有视频文件的链接和文件名和来源页链接实时展示出来,点链接可以跳转,只要不关闭网页,就一直爬取显示。

第一步:演示

python 复制代码
from flask import Flask, render_template_string, request, Response  # 新增Response支持SSE
import threading
import time
import json
import requests
from bs4 import BeautifulSoup

app = Flask(__name__)

# 全局变量
is_crawling = False
crawl_thread = None
results_stream = []  # 存储推送结果流

# 增强版HTML页面,支持SSE实时接收
HTML_TEMPLATE = '''
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>实时文件搜索引擎</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        input[type=text] { width: 300px; padding: 10px; font-size: 16px; }
        button { padding: 10px 20px; font-size: 16px; margin-left: 10px; }
        .file-item { 
            border-bottom: 1px solid #eee; padding: 15px 0; 
            background: #f9f9f9; border-radius: 8px; margin: 10px 0; 
            transition: all 0.3s;
        }
        .file-item:hover { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
        .filename { 
            color: #1a0dab; font-weight: bold; font-size: 1.1em; 
        }
        .source { 
            color: #006621; font-size: 0.9em; margin: 5px 0; 
        }
        .link { 
            color: #0066cc; text-decoration: none; word-break: break-all; 
            display: block; margin: 8px 0; font-size: 0.95em;
        }
        .timestamp { 
            color: #666; font-size: 0.8em; 
        }
        #status { margin: 20px 0; padding: 10px; background: #e6f7ff; border-radius: 4px; }
    </style>
</head>
<body>
    <h1>🔍 实时文件搜索引擎</h1>
    <div>
        <input type="text" id="keyword" placeholder="请输入要搜索的文件类型,例如:视频、文档、PDF..." value="视频">
        <button onclick="startSearch()">开始搜索</button>
        <button onclick="stopSearch()">停止搜索</button>
    </div>
    <div id="status">等待用户操作...</div>
    <hr>
    <div id="results"></div>

    <script>
        let eventSource = null;

        function startSearch() {
            const keyword = document.getElementById('keyword').value;
            if (!keyword) return alert("请输入关键词!");
            
            // 关闭旧连接
            if (eventSource) eventSource.close();
            
            // 更新状态
            document.getElementById('status').innerHTML = `正在搜索 '${keyword}'... <span style="color:green">● 连接中</span>`;
            document.getElementById('results').innerHTML = '';
            
            // 创建SSE连接
            eventSource = new EventSource('/stream?keyword=' + encodeURIComponent(keyword));
            
            eventSource.onmessage = function(event) {
                const data = JSON.parse(event.data);
                const resultsDiv = document.getElementById('results');
                
                const item = document.createElement('div');
                item.className = 'file-item';
                item.innerHTML = `
                    <div class="filename">${data.filename}</div>
                    <div class="source">来源页: ${data.source}</div>
                    <a href="${data.url}" target="_blank" class="link">${data.url}</a>
                    <div class="timestamp">发现时间: ${data.timestamp}</div>
                `;
                resultsDiv.prepend(item); // 最新结果在最上面
            };
            
            eventSource.onerror = function() {
                document.getElementById('status').innerHTML += " ● 连接异常";
            };
            
            // 开始爬取
            fetch('/start?keyword=' + encodeURIComponent(keyword));
        }

        function stopSearch() {
            if (eventSource) {
                eventSource.close();
                document.getElementById('status').innerHTML += " <span style='color:orange'>● 已手动断开</span>";
            }
            fetch('/stop');
        }
    </script>
</body>
</html>
'''

@app.route('/')
def index():
    return render_template_string(HTML_TEMPLATE)

@app.route('/start')
def start_crawling():
    global is_crawling, crawl_thread
    keyword = request.args.get('keyword', '视频')
    
    if not is_crawling:
        is_crawling = True
        crawl_thread = threading.Thread(target=crawl_task, args=(keyword,))
        crawl_thread.start()
        return "爬取已启动"
    else:
        return "已在爬取中..."

@app.route('/stop')
def stop_crawling():
    global is_crawling
    is_crawling = False
    return "已发送停止信号"

@app.route('/stream')
def stream():
    """SSE端点,实时推送结果"""
    def generate():
        while True:
            if len(results_stream) > 0:
                # 取出最新一条
                result = results_stream.pop(0)
                yield 'data: {}\n\n'.format(json.dumps(result))
            else:
                time.sleep(0.1)  # 小休一下避免过度占用CPU
    
    return Response(generate(), mimetype='text/event-stream')

def crawl_task(keyword):
    """模拟爬取任务"""
    global is_crawling
    mock_urls = [
        ("教学视频.mp4", "https://example.com/video1.mp4", "https://example.com/page1"),
        ("宣传片_高清.avi", "https://mirror-site.org/vid.avi", "https://example.com/page2"),
        ("讲座回放.flv", "https://cdn-host.net/flv/lecture.flv", "https://edu-site.com/lectures"),
        ("培训资料.mkv", "https://training-site.com/materials.mkv", "https://training-site.com/courses"),
        ("演示文稿.mov", "https://media-host.com/demo.mov", "https://corp-site.com/media")
    ]
    
    while is_crawling:
        for filename, link, source in mock_urls:
            if not is_crawling:
                break
            result_item = {
                "filename": f"[{keyword}]{filename}",
                "url": link,
                "source": source,
                "timestamp": time.strftime("%H:%M:%S")
            }
            print(f"找到文件并推送: {result_item}")
            results_stream.append(result_item)  # 添加到推送队列
            time.sleep(3)
    print("爬取结束")

if __name__ == '__main__':
    app.run(port=5000, debug=True, use_reloader=False)
相关推荐
半亩码田14 分钟前
C#转Python第3.6篇:Python 的 @property 比 C# 的 get/set 更灵活
java·python·c#
程序员与背包客_CoderZ29 分钟前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
欧叶冲冲冲38 分钟前
Python常见数据结构的CRUD(LeetCode高频版速查)
数据结构·python·leetcode
钱栈up39 分钟前
Mac 开发机一键发版不用切环境:我这样改造了团队的后端部署脚本Maven编译卡住20分钟?我靠两步定位到2处隐蔽编译错误
开发语言·python·macos
william_yangshun43 分钟前
【大模型部署实战】kimi-k3-in-c 中文版:用 176KB 纯 C99 引擎在 CPU 上跑 Kimi K3 上手指南
c语言·开发语言
CSND7401 小时前
DeepSeek Harness实测+入门教程
人工智能·python
gb42152871 小时前
ai中agent,skill Package,skill,tool,prompt,mcp等等概念的关系
python
Sagittarius_A*1 小时前
Burst Lab | PHP 审计 14|反序列化(四):字符串逃逸与绕过技巧
开发语言·安全·php·web·反序列化
名字还没想好☜1 小时前
Go 用 slices/maps 标准库泛型函数:告别手写 Contains、Sort、去重(Go 1.21)
开发语言·后端·算法·golang·go
淼澄研学1 小时前
Python实战:基于LangChain与Chroma构建企业级RAG知识库问答系统
开发语言·python·langchain