知网批量下载——服务器

知网批量下载——服务器

admin
2025年07月15日
259 阅读
python、socket、threading

服务器实现[任务分发、文件接收、入库、重跑]全自动化

标题:用 200 行 Python 把一台旧 Windows 笔记本变成「论文关键词任务调度服务器」 副标题:TCP + Excel + MySQL + schedule,一次把「任务分发、文件接收、入库、重跑」全自动化 ---

0x00 场景还原

实验室里攒了几万条关键词,需要多台学生机去第三方平台爬论文。

  • 任务列表放在 关键词.xlsx 里;
  • 学生机跑完后把 PDF/Word 回传;
  • 服务器实时去重、入库,第二天零点把“已发放”的任务重置,第二天继续跑。
  • 我不想装 Hadoop、也不想上云,就用 Python 标准库 + pandas + MySQL 在一台 Windows 老本上撸了一个极简 TCP 服务。代码一共 200 行,跑了一周稳得一批。

    ---

    0x01 技术选型一句话说明

    | 组件 | 理由 | |---|---| | socket / threading | 轻量,局域网内足够;多线程一人一线,省去异步心智负担 | | pandas | Excel 就是任务队列,读写一行代码 | | mysql-connector-python | 实验室已有 MySQL,标题去重 + 全文检索都方便 | | schedule | 每晚 0 点重置任务状态,无外部依赖 |

    ---

    0x02 核心流程 3 张图

    [学生机] <--TCP--> [Server 8050端口] 1. 请求任务 2. 得到关键词+起止页 3. 爬完回传 N 个文件 4. Server 写入 D:\lw\ 并存库

    [Excel] [MySQL] 关键词 | 下载起始页 | 是否完成 title | keywords | content -------+------------+---------- ------+----------+--------- AI医疗 | 1 | 已发放 xxx | AI医疗 | xxx.pdf

    schedule.every().day.at("00:00") ↓ reset_completed_tasks() # 把“已发放”→空,第二天重跑

    ---

    0x03 代码亮点逐行聊

    🔹 1. Excel 当队列,pandas 一行筛选

    
    python
    incomplete_tasks = df[df['是否完成'].isnull()]

    任务状态只有 3 种:已分发,Excel 里肉眼可见,出问题直接改表即可。

    🔹 2. MySQL 去重防重复入库

    
    python
    if not self.check_thesis_exists(title):
        ...
        self.update_database(title, keywords, filename)

    title 字段加了唯一索引,重复论文直接拒绝,避免学生机重复提交。

    🔹 3. TCP 自定义小包协议

  • 先收 4 字节文件数量 → 再循环收 title + filename + 文件流
  • 每个字段 1024 字节定长头,简单粗暴好调试。
  • 🔹 4. 每晚 0 点自动“清档”

    
    python
    schedule.every().day.at("00:00").do(self.reset_completed_tasks)

    配合 threading 让调度线程在后台跑,主线程专心 accept。

    ---

    0x04 运行方式

  • 装好依赖
  • 
    bash
       pip install pandas mysql-connector-python schedule
       
    
  • 准备 Excel 模板
  • 表头:关键词 | 下载起始页 | 下载篇数 | 是否完成

  • 启动服务器
  • 
    bash
       python tcp_server.py
       
    
  • 学生机示例脚本(伪代码)
  • 
    python
       s = socket()
       s.connect(('192.168.1.100', 8050))
       task = s.recv(1024).decode()       # 关键词: AI医疗\n起始页: 1\n下载篇数: 20
       # ... 爬 ...
       s.sendall(str(len(files)).encode())  # 先发数量
       for f in files:
           s.sendall(title.encode())
           s.sendall(filename.encode())
           s.sendall(open(f,'rb').read())
       
    

    ---

    0x05 踩坑小结

    | 坑 | 解决 | |---|---| | Windows 路径反斜杠 | 全部 os.path.join,禁止手写 D:\lw | | Excel 被占用 | to_excel 前先 df.copy() 再写,防止 pandas 锁表 | | MySQL 连接断掉 | self.db_connection.ping(reconnect=True) 在每次操作前检查 | | schedule 阻塞 | 单独开 daemon 线程,主线程只负责 accept |---

    0x06 展望

  • 把 Excel 换成 Redis 列表,秒变高并发队列;
  • 给文件加 MD5 校验,防止传输损坏;
  • 用 asyncio 重写,单线程也能撑 1k 并发。
  • 但,目前这 200 行已让实验室同学摆脱 U 盘拷来拷去的日子。 如果你也在寻找「最小可用」的论文收集方案,不妨直接拿去改。 Happy coding!

    相关文章

    您可能感兴趣的其他文章

    示例文章标题

    这是一篇示例文章的摘要,展示相关文章的内容...

    2024-01-01 阅读更多 →

    另一篇示例文章

    这是另一篇示例文章的摘要,展示相关文章的内容...

    2024-01-02 阅读更多 →

    第三篇示例文章

    这是第三篇示例文章的摘要,展示相关文章的内容...

    2024-01-03 阅读更多 →