
Daily Paper Digest
- 9 installs
- 33 repo stars
- Updated April 26, 2026
- bighardperson/computer-science-skills-collection
daily-paper-digest is a skill that aggregates the latest arXiv and HuggingFace AI papers daily and pushes a formatted digest to chat apps.
About
daily-paper-digest is a skill that automatically gathers the latest AI papers from arXiv and HuggingFace and pushes a formatted digest to chat apps such as Feishu, Slack or Discord. It supports category and keyword filtering via a sources.json config and can run on a daily cron schedule. A developer or researcher uses it to stay current on AI research without manual searching.
- Aggregates the latest AI papers from arXiv and HuggingFace daily
- Formats and pushes digests to chat apps (Feishu, Slack, Discord)
- Configurable sources, categories and keyword filters; schedulable via cron
Daily Paper Digest by the numbers
- 9 all-time installs (skills.sh)
- Ranked #1,497 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
daily-paper-digest capabilities & compatibility
- Capabilities
- paper digest · research aggregation · web scraping
- Works with
- slack
- Use cases
- research · web scraping
- Pricing
- Free
What daily-paper-digest says it does
每日 AI 论文速递,自动聚合 arXiv 和 HuggingFace 的最新论文并推送到聊天应用。
每天自动从 arXiv 和 HuggingFace 抓取最新 AI 论文,格式化后推送到你的聊天应用(飞书、Slack、Discord 等)。
npx skills add https://github.com/bighardperson/computer-science-skills-collection --skill daily-paper-digestAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 9 |
|---|---|
| repo stars | ★ 33 |
| Last updated | April 26, 2026 |
| Repository | bighardperson/computer-science-skills-collection ↗ |
What it does
Automatically fetch and push a daily digest of the latest AI papers from arXiv and HuggingFace to a chat app.
Who is it for?
staying current on AI research via automated arXiv and HuggingFace digests
When should I use this skill?
you want a scheduled digest of the latest AI papers pushed to a chat app
What you get
A daily formatted digest of new AI papers delivered to your chat app.
By the numbers
- 3 bundled tools
- arXiv categories include cs.AI, cs.CL, cs.CV, cs.LG
Files
📚 每日 AI 论文速递
每天自动从 arXiv 和 HuggingFace 抓取最新 AI 论文,格式化后推送到你的聊天应用(飞书、Slack、Discord 等)。
工具(Tools)
fetch_daily_papers
获取今日最新论文速递。
用法:
python3 main.py参数:
- 无(自动读取
config/sources.json中的配置)
返回:
- 格式化的论文列表,包含标题、作者、摘要、链接
---
search_arxiv_papers
搜索特定主题的 arXiv 论文。
用法:
python3 arxiv_fetcher.py参数(在代码中修改):
query:搜索关键词,如 "large language model"max_results:最大返回数量(默认 5)
返回:
- 匹配的论文列表
---
fetch_huggingface_papers
获取 HuggingFace 每日热门论文。
用法:
python3 huggingface_fetcher.py参数:
- 无(直接爬取
https://huggingface.co/papers)
返回:
- 热门论文列表,含点赞数
---
配置
编辑 config/sources.json 来自定义信息源和过滤规则:
{
"sources": [
{
"name": "arxiv",
"enabled": true,
"categories": ["cs.AI", "cs.CL", "cs.CV", "cs.LG"],
"max_results": 10
},
{
"name": "huggingface",
"enabled": true,
"max_results": 10
}
],
"filter": {
"keywords": ["LLM", "transformer"],
"exclude_keywords": []
}
}arXiv 常用分类
| 代码 | 含义 |
|---|---|
cs.AI | 人工智能 |
cs.CL | 计算语言学/NLP |
cs.CV | 计算机视觉 |
cs.LG | 机器学习 |
cs.NE | 神经网络 |
cs.RO | 机器人 |
stat.ML | 统计机器学习 |
---
安装与使用
1. 安装依赖
pip3 install -r requirements.txt2. 运行测试
python3 test.py3. 获取今日论文
python3 main.py4. 定时自动运行(配合 OpenClaw 调度器)
在 OpenClaw 中配置 Cron 表达式(例如每天 9:00):
0 9 * * *---
在 OpenClaw 中触发
在聊天应用中发送以下任意内容即可触发:
论文速递今日论文最新论文/papers/digest
---
依赖
arxiv— arXiv 官方 Python 客户端requests— HTTP 请求beautifulsoup4— HTML 解析feedparser— RSS/Atom 解析
---
示例输出
╔══════════════════════════════════════════════════════════╗
║ 🎓 AI 论文每日速递 - 2026年02月20日 ║
╚══════════════════════════════════════════════════════════╝
📊 今日共收录 15 篇论文
============================================================
📄 论文 1
============================================================
📌 标题: Attention Is All You Need
👥 作者: Ashish Vaswani, Noam Shazeer 等 8 人
🏷️ 来源: ARXIV | 日期: 2026-02-20
📝 摘要:
The dominant sequence transduction models are based on...
🔗 arXiv: http://arxiv.org/abs/1706.03762
📥 PDF: http://arxiv.org/pdf/1706.03762---
文件结构
daily-paper-digest/
├── SKILL.md ← 本文件(ClawHub 规范)
├── main.py ← 主程序
├── arxiv_fetcher.py ← arXiv 模块
├── huggingface_fetcher.py ← HuggingFace 模块
├── requirements.txt ← Python 依赖
└── config/
├── sources.json ← 默认配置
└── sources_llm.json ← LLM 专用配置{
"ownerId": "kn791b3prmq172nkkkf52kg8y181ep3e",
"slug": "daily-paper-digest",
"version": "1.0.0",
"publishedAt": 1771587246433
}{
"version": 1,
"registry": "https://clawhub.ai",
"slug": "daily-paper-digest",
"installedVersion": "1.0.0",
"installedAt": 1776068341793
}
"""
arXiv 论文爬取模块
"""
import arxiv
from datetime import datetime, timedelta
from typing import List, Dict
import logging
logger = logging.getLogger(__name__)
class ArxivFetcher:
"""arXiv 论文获取器"""
def __init__(self, categories: List[str], max_results: int = 10):
"""
初始化 arXiv 获取器
Args:
categories: 论文分类列表,如 ['cs.AI', 'cs.CL']
max_results: 每个分类最大返回结果数
"""
self.categories = categories
self.max_results = max_results
def fetch_daily_papers(self) -> List[Dict]:
"""
获取每日最新论文
Returns:
论文列表,每篇论文包含标题、作者、摘要、链接等信息
"""
papers = []
yesterday = datetime.now() - timedelta(days=1)
date_str = yesterday.strftime('%Y%m%d')
for category in self.categories:
try:
logger.info(f"正在获取 {category} 分类的论文...")
# 构建查询
search = arxiv.Search(
query=f"cat:{category}",
max_results=self.max_results,
sort_by=arxiv.SortCriterion.SubmittedDate,
sort_order=arxiv.SortOrder.Descending
)
# 获取结果
for result in search.results():
# 只获取最近一天的论文
if result.published.date() >= yesterday.date():
paper = {
'title': result.title,
'authors': [author.name for author in result.authors],
'abstract': result.summary,
'pdf_url': result.pdf_url,
'arxiv_url': result.entry_id,
'published': result.published.strftime('%Y-%m-%d'),
'category': category,
'source': 'arxiv'
}
papers.append(paper)
except Exception as e:
logger.error(f"获取 {category} 论文失败: {str(e)}")
logger.info(f"从 arXiv 获取了 {len(papers)} 篇论文")
return papers
def search_papers(self, query: str, max_results: int = 5) -> List[Dict]:
"""
搜索特定主题的论文
Args:
query: 搜索关键词
max_results: 最大返回结果数
Returns:
论文列表
"""
papers = []
try:
search = arxiv.Search(
query=query,
max_results=max_results,
sort_by=arxiv.SortCriterion.SubmittedDate,
sort_order=arxiv.SortOrder.Descending
)
for result in search.results():
paper = {
'title': result.title,
'authors': [author.name for author in result.authors],
'abstract': result.summary,
'pdf_url': result.pdf_url,
'arxiv_url': result.entry_id,
'published': result.published.strftime('%Y-%m-%d'),
'source': 'arxiv'
}
papers.append(paper)
except Exception as e:
logger.error(f"搜索论文失败: {str(e)}")
return papers
if __name__ == "__main__":
# 测试代码
logging.basicConfig(level=logging.INFO)
fetcher = ArxivFetcher(categories=['cs.AI', 'cs.CL'], max_results=5)
papers = fetcher.fetch_daily_papers()
print(f"\n找到 {len(papers)} 篇论文:")
for i, paper in enumerate(papers, 1):
print(f"\n{i}. {paper['title']}")
print(f" 作者: {', '.join(paper['authors'][:3])}")
print(f" 链接: {paper['arxiv_url']}")
{
"sources": [
{
"name": "arxiv",
"enabled": true,
"description": "arXiv每日论文速递 - 专注于大语言模型",
"categories": [
"cs.CL",
"cs.AI",
"cs.LG"
],
"max_results": 5,
"update_interval": "daily"
},
{
"name": "huggingface",
"enabled": true,
"description": "HuggingFace每日热门论文",
"url": "https://huggingface.co/papers",
"max_results": 5,
"update_interval": "daily"
}
],
"output_format": {
"include_abstract": true,
"include_authors": true,
"include_links": true,
"language": "zh-CN"
},
"filter": {
"keywords": [
"LLM",
"Large Language Model",
"GPT",
"Transformer",
"BERT",
"ChatGPT",
"agent",
"reasoning"
],
"exclude_keywords": []
}
}
{
"sources": [
{
"name": "arxiv",
"enabled": true,
"description": "arXiv每日论文速递",
"categories": [
"cs.AI",
"cs.CL",
"cs.CV",
"cs.LG",
"cs.NE"
],
"max_results": 10,
"update_interval": "daily"
},
{
"name": "huggingface",
"enabled": true,
"description": "HuggingFace每日论文",
"url": "https://huggingface.co/papers",
"max_results": 10,
"update_interval": "daily"
}
],
"output_format": {
"include_abstract": true,
"include_authors": true,
"include_links": true,
"language": "zh-CN"
},
"filter": {
"keywords": [],
"exclude_keywords": []
}
}
"""
HuggingFace 论文爬取模块
"""
import requests
from bs4 import BeautifulSoup
from typing import List, Dict
import logging
from datetime import datetime
logger = logging.getLogger(__name__)
class HuggingFaceFetcher:
"""HuggingFace 每日论文获取器"""
def __init__(self, max_results: int = 10):
"""
初始化 HuggingFace 获取器
Args:
max_results: 最大返回结果数
"""
self.base_url = "https://huggingface.co/papers"
self.max_results = max_results
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def fetch_daily_papers(self) -> List[Dict]:
"""
获取 HuggingFace 每日热门论文
Returns:
论文列表
"""
papers = []
try:
logger.info("正在获取 HuggingFace 每日论文...")
# 请求页面
response = requests.get(self.base_url, headers=self.headers, timeout=10)
response.raise_for_status()
# 解析 HTML
soup = BeautifulSoup(response.text, 'html.parser')
# 查找论文卡片
paper_cards = soup.find_all('article', class_='overview-card-wrapper', limit=self.max_results)
for card in paper_cards:
try:
# 提取论文信息
title_elem = card.find('h3')
title = title_elem.text.strip() if title_elem else "未知标题"
# 提取链接
link_elem = card.find('a', href=True)
paper_link = f"https://huggingface.co{link_elem['href']}" if link_elem else ""
# 提取作者
authors_elem = card.find('p', class_='text-sm')
authors = [authors_elem.text.strip()] if authors_elem else []
# 提取摘要
abstract_elem = card.find('p', class_='line-clamp-3')
abstract = abstract_elem.text.strip() if abstract_elem else ""
# 提取点赞数
likes_elem = card.find('span', class_='text-sm')
likes = likes_elem.text.strip() if likes_elem else "0"
paper = {
'title': title,
'authors': authors,
'abstract': abstract,
'url': paper_link,
'likes': likes,
'published': datetime.now().strftime('%Y-%m-%d'),
'source': 'huggingface'
}
papers.append(paper)
except Exception as e:
logger.warning(f"解析单篇论文失败: {str(e)}")
continue
logger.info(f"从 HuggingFace 获取了 {len(papers)} 篇论文")
except Exception as e:
logger.error(f"获取 HuggingFace 论文失败: {str(e)}")
return papers
def fetch_paper_details(self, paper_url: str) -> Dict:
"""
获取单篇论文的详细信息
Args:
paper_url: 论文 URL
Returns:
论文详细信息
"""
try:
response = requests.get(paper_url, headers=self.headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
# 这里可以根据实际页面结构提取更多信息
# 返回基本信息
return {
'url': paper_url,
'fetched_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
except Exception as e:
logger.error(f"获取论文详情失败: {str(e)}")
return {}
if __name__ == "__main__":
# 测试代码
logging.basicConfig(level=logging.INFO)
fetcher = HuggingFaceFetcher(max_results=5)
papers = fetcher.fetch_daily_papers()
print(f"\n找到 {len(papers)} 篇论文:")
for i, paper in enumerate(papers, 1):
print(f"\n{i}. {paper['title']}")
print(f" 点赞: {paper['likes']}")
print(f" 链接: {paper['url']}")
"""
每日论文速递主程序
整合 arXiv 和 HuggingFace 的论文信息
"""
import json
import os
import logging
from typing import List, Dict
from datetime import datetime
from arxiv_fetcher import ArxivFetcher
from huggingface_fetcher import HuggingFaceFetcher
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class PaperDigest:
"""论文速递主类"""
def __init__(self, config_path: str = "config/sources.json"):
"""
初始化论文速递
Args:
config_path: 配置文件路径
"""
self.config = self._load_config(config_path)
self.arxiv_fetcher = None
self.hf_fetcher = None
self._init_fetchers()
def _load_config(self, config_path: str) -> Dict:
"""加载配置文件"""
try:
# 获取脚本所在目录
script_dir = os.path.dirname(os.path.abspath(__file__))
full_path = os.path.join(script_dir, config_path)
with open(full_path, 'r', encoding='utf-8') as f:
config = json.load(f)
logger.info(f"成功加载配置文件: {config_path}")
return config
except Exception as e:
logger.error(f"加载配置文件失败: {str(e)}")
# 返回默认配置
return {
"sources": [],
"output_format": {
"include_abstract": True,
"include_authors": True,
"include_links": True,
"language": "zh-CN"
}
}
def _init_fetchers(self):
"""初始化各个信息源的获取器"""
for source in self.config.get('sources', []):
if not source.get('enabled', False):
continue
if source['name'] == 'arxiv':
categories = source.get('categories', ['cs.AI'])
max_results = source.get('max_results', 10)
self.arxiv_fetcher = ArxivFetcher(categories, max_results)
logger.info("已初始化 arXiv 获取器")
elif source['name'] == 'huggingface':
max_results = source.get('max_results', 10)
self.hf_fetcher = HuggingFaceFetcher(max_results)
logger.info("已初始化 HuggingFace 获取器")
def fetch_all_papers(self) -> List[Dict]:
"""
从所有启用的信息源获取论文
Returns:
所有论文的列表
"""
all_papers = []
# 获取 arXiv 论文
if self.arxiv_fetcher:
try:
arxiv_papers = self.arxiv_fetcher.fetch_daily_papers()
all_papers.extend(arxiv_papers)
logger.info(f"从 arXiv 获取了 {len(arxiv_papers)} 篇论文")
except Exception as e:
logger.error(f"获取 arXiv 论文失败: {str(e)}")
# 获取 HuggingFace 论文
if self.hf_fetcher:
try:
hf_papers = self.hf_fetcher.fetch_daily_papers()
all_papers.extend(hf_papers)
logger.info(f"从 HuggingFace 获取了 {len(hf_papers)} 篇论文")
except Exception as e:
logger.error(f"获取 HuggingFace 论文失败: {str(e)}")
return all_papers
def filter_papers(self, papers: List[Dict]) -> List[Dict]:
"""
根据配置过滤论文
Args:
papers: 论文列表
Returns:
过滤后的论文列表
"""
filter_config = self.config.get('filter', {})
keywords = filter_config.get('keywords', [])
exclude_keywords = filter_config.get('exclude_keywords', [])
if not keywords and not exclude_keywords:
return papers
filtered_papers = []
for paper in papers:
title = paper.get('title', '').lower()
abstract = paper.get('abstract', '').lower()
text = f"{title} {abstract}"
# 检查排除关键词
if exclude_keywords:
if any(keyword.lower() in text for keyword in exclude_keywords):
continue
# 检查包含关键词
if keywords:
if any(keyword.lower() in text for keyword in keywords):
filtered_papers.append(paper)
else:
filtered_papers.append(paper)
logger.info(f"过滤后剩余 {len(filtered_papers)} 篇论文")
return filtered_papers
def format_paper(self, paper: Dict, index: int) -> str:
"""
格式化单篇论文信息
Args:
paper: 论文信息
index: 序号
Returns:
格式化后的文本
"""
output_format = self.config.get('output_format', {})
# 构建输出
lines = []
lines.append(f"\n{'='*60}")
lines.append(f"📄 论文 {index}")
lines.append(f"{'='*60}")
lines.append(f"\n📌 标题: {paper.get('title', '未知')}")
# 作者信息
if output_format.get('include_authors', True):
authors = paper.get('authors', [])
if authors:
author_str = ', '.join(authors[:5]) # 最多显示5个作者
if len(authors) > 5:
author_str += f" 等 {len(authors)} 人"
lines.append(f"👥 作者: {author_str}")
# 来源和发布日期
source = paper.get('source', '未知').upper()
published = paper.get('published', '未知')
lines.append(f"🏷️ 来源: {source} | 日期: {published}")
# 摘要
if output_format.get('include_abstract', True):
abstract = paper.get('abstract', '')
if abstract:
# 限制摘要长度
if len(abstract) > 300:
abstract = abstract[:300] + '...'
lines.append(f"\n📝 摘要:\n{abstract}")
# 链接
if output_format.get('include_links', True):
if paper.get('source') == 'arxiv':
lines.append(f"\n🔗 arXiv: {paper.get('arxiv_url', '')}")
lines.append(f"📥 PDF: {paper.get('pdf_url', '')}")
elif paper.get('source') == 'huggingface':
lines.append(f"\n🔗 链接: {paper.get('url', '')}")
likes = paper.get('likes', '0')
lines.append(f"👍 点赞: {likes}")
return '\n'.join(lines)
def format_digest(self, papers: List[Dict]) -> str:
"""
格式化论文速递报告
Args:
papers: 论文列表
Returns:
完整的报告文本
"""
if not papers:
return "📭 今日暂无新论文"
# 标题
title = f"""
╔══════════════════════════════════════════════════════════╗
║ 🎓 AI 论文每日速递 - {datetime.now().strftime('%Y年%m月%d日')} ║
╚══════════════════════════════════════════════════════════╝
📊 今日共收录 {len(papers)} 篇论文
"""
# 格式化每篇论文
formatted_papers = [self.format_paper(paper, i+1) for i, paper in enumerate(papers)]
# 统计信息
arxiv_count = sum(1 for p in papers if p.get('source') == 'arxiv')
hf_count = sum(1 for p in papers if p.get('source') == 'huggingface')
footer = f"""
\n{'='*60}
📈 信息源统计:
• arXiv: {arxiv_count} 篇
• HuggingFace: {hf_count} 篇
⏰ 更新时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
{'='*60}
"""
return title + '\n'.join(formatted_papers) + footer
def run(self) -> str:
"""
执行论文速递
Returns:
格式化后的报告文本
"""
logger.info("开始执行每日论文速递...")
# 获取所有论文
papers = self.fetch_all_papers()
# 过滤论文
filtered_papers = self.filter_papers(papers)
# 格式化输出
digest = self.format_digest(filtered_papers)
logger.info("论文速递执行完成")
return digest
def main():
"""主函数,用于 OpenClaw skill 调用"""
digest = PaperDigest()
result = digest.run()
print(result)
return result
if __name__ == "__main__":
main()
📚 每日论文速递 Skill
一个用于 OpenClaw 的每日 AI 论文速递技能,自动聚合 arXiv 和 HuggingFace 的最新论文。
✨ 特性
- 🔍 自动抓取 arXiv 最新论文(支持多个分类)
- 🤗 获取 HuggingFace 每日热门论文
- 🎯 支持关键词过滤
- 📅 每日定时推送
- 🎨 优雅的格式化输出
- ⚙️ 灵活的配置选项
📁 项目结构
daily_paper_digest/
├── config/
│ └── sources.json # 信息源配置文件
├── skill.json # Skill 定义文件
├── main.py # 主程序入口
├── arxiv_fetcher.py # arXiv 爬取模块
├── huggingface_fetcher.py # HuggingFace 爬取模块
├── requirements.txt # Python 依赖
└── README.md # 本文档🚀 快速开始
1. 安装依赖
cd daily_paper_digest
pip install -r requirements.txt2. 配置信息源
编辑 config/sources.json 文件:
{
"sources": [
{
"name": "arxiv",
"enabled": true,
"categories": [
"cs.AI", // 人工智能
"cs.CL", // 计算语言学
"cs.CV", // 计算机视觉
"cs.LG", // 机器学习
"cs.NE" // 神经网络
],
"max_results": 10
},
{
"name": "huggingface",
"enabled": true,
"max_results": 10
}
],
"filter": {
"keywords": ["LLM", "transformer", "GPT"],
"exclude_keywords": ["medical", "biology"]
}
}3. 测试运行
# 测试 arXiv 模块
python arxiv_fetcher.py
# 测试 HuggingFace 模块
python huggingface_fetcher.py
# 运行完整程序
python main.py📝 配置说明
arXiv 分类代码
常用的 arXiv 分类:
cs.AI- 人工智能cs.CL- 计算语言学/自然语言处理cs.CV- 计算机视觉cs.LG- 机器学习cs.NE- 神经网络cs.RO- 机器人stat.ML- 统计机器学习
更多分类请参考:https://arxiv.org/category_taxonomy
输出格式配置
{
"output_format": {
"include_abstract": true, // 是否包含摘要
"include_authors": true, // 是否包含作者
"include_links": true, // 是否包含链接
"language": "zh-CN" // 输出语言
}
}过滤器配置
{
"filter": {
"keywords": ["LLM", "GPT"], // 包含关键词(留空表示不过滤)
"exclude_keywords": ["medical"] // 排除关键词
}
}🔧 OpenClaw 集成
1. 部署到 OpenClaw
将整个 daily_paper_digest 文件夹复制到 OpenClaw 的 skills 目录:
cp -r daily_paper_digest /path/to/openclaw/skills/2. 在 OpenClaw 中使用
触发方式:
1. 关键词触发:在聊天中发送 "论文速递"、"今日论文"、"最新论文" 2. 命令触发:发送 /papers 或 /digest 3. 定时触发:每天早上 9:00 自动推送(在 skill.json 中配置)
3. 修改定时任务
编辑 skill.json 中的 schedule 字段(Cron 表达式):
{
"schedule": "0 9 * * *" // 每天 9:00
}常用 Cron 表达式:
0 9 * * *- 每天 9:000 9,18 * * *- 每天 9:00 和 18:000 9 * * 1-5- 工作日 9:00
📊 输出示例
╔══════════════════════════════════════════════════════════╗
║ 🎓 AI 论文每日速递 - 2026年02月20日 ║
╚══════════════════════════════════════════════════════════╝
📊 今日共收录 15 篇论文
============================================================
📄 论文 1
============================================================
📌 标题: Attention Is All You Need
👥 作者: Ashish Vaswani, Noam Shazeer, Niki Parmar 等 8 人
🏷️ 来源: ARXIV | 日期: 2026-02-20
📝 摘要:
The dominant sequence transduction models are based on complex
recurrent or convolutional neural networks...
🔗 arXiv: http://arxiv.org/abs/1706.03762
📥 PDF: http://arxiv.org/pdf/1706.03762
...
============================================================
📈 信息源统计:
• arXiv: 10 篇
• HuggingFace: 5 篇
⏰ 更新时间: 2026-02-20 09:00:00
============================================================🛠️ 高级用法
手动获取特定主题论文
from arxiv_fetcher import ArxivFetcher
fetcher = ArxivFetcher(categories=['cs.AI'], max_results=5)
papers = fetcher.search_papers("large language model", max_results=10)
for paper in papers:
print(f"标题: {paper['title']}")
print(f"链接: {paper['arxiv_url']}\n")自定义输出格式
修改 main.py 中的 format_paper() 和 format_digest() 方法。
🐛 故障排除
1. arXiv API 访问失败
- 检查网络连接
- 确认是否被限流(arXiv 有访问频率限制)
- 尝试使用代理
2. HuggingFace 页面解析失败
- HuggingFace 页面结构可能更新,需要调整
huggingface_fetcher.py中的解析逻辑 - 检查是否被反爬虫机制拦截
3. 依赖安装失败
# 使用清华镜像源
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple📈 未来计划
- [ ] 支持更多论文源(Papers with Code, Semantic Scholar)
- [ ] 添加论文摘要的中文翻译
- [ ] 支持订阅特定关键词
- [ ] 论文相关性推荐
- [ ] 导出为 PDF/Markdown
- [ ] Web Dashboard
📄 许可证
MIT License
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📧 联系方式
如有问题,请通过以下方式联系:
- 提交 GitHub Issue
- OpenClaw 社区讨论
---
享受每日论文速递!📚✨
# 每日论文速递 Skill 依赖
# arXiv API 客户端
arxiv==2.1.0
# HTTP 请求
requests==2.31.0
# HTML 解析
beautifulsoup4==4.12.3
# XML/Feed 解析
feedparser==6.0.11
# HTML 标签处理
lxml==5.1.0
# 字符编码检测
chardet==5.2.0
# 日期时间处理
python-dateutil==2.8.2
{
"name": "daily_paper_digest",
"version": "1.0.0",
"description": "每日AI论文速递,聚合arxiv和HuggingFace的最新论文",
"author": "OpenClaw User",
"type": "scheduled",
"schedule": "0 9 * * *",
"trigger": {
"keywords": ["论文速递", "今日论文", "最新论文", "paper digest"],
"commands": ["/papers", "/digest"]
},
"dependencies": [
"arxiv",
"requests",
"beautifulsoup4",
"feedparser"
],
"config": {
"config_file": "config/sources.json"
},
"entry": "main.py"
}
"""
测试脚本 - 用于验证各个模块是否正常工作
"""
import sys
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def test_imports():
"""测试依赖导入"""
print("\n" + "="*60)
print("📦 测试依赖导入...")
print("="*60)
try:
import arxiv
print("✅ arxiv")
except ImportError:
print("❌ arxiv - 请运行: pip install arxiv")
return False
try:
import requests
print("✅ requests")
except ImportError:
print("❌ requests - 请运行: pip install requests")
return False
try:
from bs4 import BeautifulSoup
print("✅ beautifulsoup4")
except ImportError:
print("❌ beautifulsoup4 - 请运行: pip install beautifulsoup4")
return False
try:
import feedparser
print("✅ feedparser")
except ImportError:
print("❌ feedparser - 请运行: pip install feedparser")
return False
print("\n✅ 所有依赖已安装\n")
return True
def test_arxiv_fetcher():
"""测试 arXiv 模块"""
print("\n" + "="*60)
print("🔬 测试 arXiv 模块...")
print("="*60)
try:
from arxiv_fetcher import ArxivFetcher
# 创建获取器(只获取1篇论文用于测试)
fetcher = ArxivFetcher(categories=['cs.AI'], max_results=1)
print("✅ ArxivFetcher 初始化成功")
# 搜索论文
print("🔍 搜索最新论文...")
papers = fetcher.search_papers("machine learning", max_results=2)
if papers:
print(f"✅ 成功获取 {len(papers)} 篇论文")
print(f"\n示例论文:")
print(f" 标题: {papers[0]['title'][:60]}...")
print(f" 链接: {papers[0]['arxiv_url']}")
else:
print("⚠️ 未获取到论文(可能是网络问题)")
return True
except Exception as e:
print(f"❌ arXiv 模块测试失败: {str(e)}")
return False
def test_huggingface_fetcher():
"""测试 HuggingFace 模块"""
print("\n" + "="*60)
print("🤗 测试 HuggingFace 模块...")
print("="*60)
try:
from huggingface_fetcher import HuggingFaceFetcher
# 创建获取器
fetcher = HuggingFaceFetcher(max_results=2)
print("✅ HuggingFaceFetcher 初始化成功")
# 获取论文
print("🔍 获取热门论文...")
papers = fetcher.fetch_daily_papers()
if papers:
print(f"✅ 成功获取 {len(papers)} 篇论文")
print(f"\n示例论文:")
print(f" 标题: {papers[0]['title'][:60]}...")
print(f" 链接: {papers[0]['url']}")
else:
print("⚠️ 未获取到论文(可能是网络问题或页面结构变化)")
return True
except Exception as e:
print(f"❌ HuggingFace 模块测试失败: {str(e)}")
return False
def test_main_module():
"""测试主模块"""
print("\n" + "="*60)
print("🚀 测试主模块...")
print("="*60)
try:
from main import PaperDigest
# 创建实例
digest = PaperDigest()
print("✅ PaperDigest 初始化成功")
# 注意:这里不实际运行 fetch_all_papers,因为可能需要较长时间
print("✅ 主模块加载正常")
return True
except Exception as e:
print(f"❌ 主模块测试失败: {str(e)}")
return False
def main():
"""运行所有测试"""
print("\n" + "="*60)
print("🧪 开始运行测试套件")
print("="*60)
results = []
# 测试依赖
results.append(("依赖导入", test_imports()))
# 测试模块
if results[0][1]: # 只有依赖正常才继续测试
results.append(("arXiv 模块", test_arxiv_fetcher()))
results.append(("HuggingFace 模块", test_huggingface_fetcher()))
results.append(("主模块", test_main_module()))
# 输出结果
print("\n" + "="*60)
print("📊 测试结果汇总")
print("="*60)
for name, result in results:
status = "✅ 通过" if result else "❌ 失败"
print(f"{name}: {status}")
all_passed = all(result for _, result in results)
print("\n" + "="*60)
if all_passed:
print("🎉 所有测试通过!")
print("="*60)
print("\n下一步:")
print("1. 运行 python main.py 获取今日论文")
print("2. 编辑 config/sources.json 自定义配置")
print("3. 部署到 OpenClaw")
else:
print("⚠️ 部分测试失败,请检查错误信息")
print("="*60)
print("\n故障排除:")
print("1. 确保已安装所有依赖: pip install -r requirements.txt")
print("2. 检查网络连接")
print("3. 查看详细错误信息")
print("")
return 0 if all_passed else 1
if __name__ == "__main__":
sys.exit(main())
Related skills
FAQ
Which sources does daily-paper-digest use?
arXiv and HuggingFace papers.
Where can it send the digest?
Chat apps such as Feishu, Slack and Discord.