Metadata-Version: 2.4
Name: gPaper
Version: 0.3.0
Summary: Resolve a paper from a URL, DOI, or title and download the best available PDF.
License-Expression: MIT
Project-URL: Homepage, https://github.com/WMGray/getPaper
Project-URL: Repository, https://github.com/WMGray/getPaper
Keywords: paper,pdf,doi,arxiv,research
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: lxml>=5.0.0
Dynamic: license-file

# 📄 gPaper

[![Version](https://img.shields.io/badge/version-0.3.0-blue?style=flat-square)](pyproject.toml)
[![GitHub last commit](https://img.shields.io/github/last-commit/WMGray/getPaper?style=flat-square)](https://github.com/WMGray/getPaper/commits/main)
[![License: MIT](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue?style=flat-square)](pyproject.toml)

`gPaper` 是一款专为学术研究人员设计的、高可用性的单篇论文 PDF 自动获取工具。

只需提供论文的 **URL**、**DOI** 或**标题**，工具便会通过精密的优先级决策树，自动在各大数据库、公开学术索引及出版商落地页中游走，尽最大可能为您下载最高质量的正式版公开 PDF 文件。当无法自动获取时，它还会智能生成规范的建议文件名与保存路径，方便您进行人工干预。

## ✨ 核心特性

- **多维度输入**：灵活支持 URL（arXiv、会议落地页、PDF 直链等）、DOI 或纯文本标题解析。
- **智能降级与回退 (Fallback)**：优先尝试 CVPR、NeurIPS、ACL 等顶会的官方正式公开版；若遇阻，依次回退至公开学术索引（Semantic Scholar, OpenAlex 等）、DOI 落地页解析，最后兜底至 arXiv 预印本。
- **S2 双检索与 PDF 兜底**：接入 Semantic Scholar 时，同时支持 `DOI` 精确检索与 `Title` 模糊检索；若 S2 暴露 `openAccessPdf` 或 `reader` 入口，程序会自行探测候选链接并通过 `%PDF-` 魔数校验后再下载。
- **Probe Trace 输出**：终端摘要会打印完整探针链路，包括输入归一化、S2 detail、S2 bulk search、候选 PDF probe 与最终 PDF probe。
- **Venue 标准化与官方下载路由**：会先统一标准化 `venue`（转小写、去年份、清洗 `/ - & : ()` 等分隔符），再映射到统一会议 code 与 source family，保证全称/缩写都能打通官方渠道。
- **严格的内容校验**：底层执行严格的 `%PDF-` 文件头签名校验，彻底杜绝将需登录的 HTML 拦截页或错误信息保存为失效 PDF。
- **自适应反爬与限流处理**：内置 HTTP 429 智能退避重试机制，复用 Session 连接池与一致的浏览器指纹，大幅提升解析与下载成功率。

## 🔄 核心工作流与多级回退策略

`gPaper` 采用严格的**分层模块化架构**。无论您的初始线索多么稀缺，系统都会尝试自顶向下地穿越以下层级，直至找到最终的 PDF：

### 1. 输入层 (Input)
当前支持 5 类输入，都会先做统一归一化：
*   **DOI**：如 `10.1109/CVPR.2018.00813`
*   **DOI URL**：如 `https://doi.org/10.1109/CVPR.2018.00813`
*   **arXiv URL**：如 `https://arxiv.org/abs/2503.00986`
*   **标题**：纯文本 title 检索
*   **PDF URL**：直接 PDF 链接，下载后再尽量补全元信息

### 2. DOI / DOI URL 主链
对于 `DOI` 与 `DOI URL`，当前流程是：
1. 先用 `DOI:<doi>` 调用 Semantic Scholar detail
2. 若识别到官方开放会议渠道（如 `CVPR`、`WACV`、`AAAI`、`ICLR`），优先走官方渠道
3. 官方渠道不可用时，再尝试 S2 的 `openAccessPdf` / `reader` 候选
4. 若 S2 结果带有 `arXiv ID`，则回退到 arXiv PDF
5. 若都失败，返回“已识别论文，但无可公开下载 PDF”

> 对于 `DOI` 中直接包含会议缩写的情况（如 `CVPR`、`ICCV`、`WACV`），程序也会自动补一个 `venue hint`，作为官方渠道匹配的兜底。

### 3. arXiv URL 主链
对于 `arXiv URL`，当前流程是：
1. 先解析出 `arXiv ID`
2. 通过 `arXiv ID` 直查 Semantic Scholar detail
3. 若 S2 返回 DOI，则补全正式发表信息，并复用 DOI 主链
4. 若 S2 已能补出 `venue/year/title`，会先尝试官方会议渠道
5. 正式发表版本不可下载时，最终回退到 arXiv PDF

### 4. Title / PDF URL 主链
*   **Title**：优先使用 **Semantic Scholar bulk search**，按 `标题`、`标题+年份`、`标题+venue`、`openAccessPdf=true` 组合查询，再在本地按标题相似度、年份、venue、DOI 重排；选中最佳候选后复用 DOI 主链
*   **PDF URL**：先从 URL 中抽取 `DOI`、`venue`、`year`、文件名 title 线索，通过 S2 补全元信息后再下载；若补全失败，仍保留原始 PDF 直链继续下载

### 5. 核心下载与文件头校验 (Downloader & Validation)
任何一条链路发现的“候选 PDF 链接”，在最终落盘前都必须经过严苛的体检：
*   **嗅探校验**：流式加载候选文件的前 4KB 数据，严格检查其是否包含底层的 `b"%PDF-"` 签名。
*   **防误判机制**：彻底防止因遭遇出版商的付费墙（Paywall）或风控，而把各类要求登录的 HTML 错误页面错误地保存为“假 PDF”。

### 6. 代码结构
当前核心模块拆分如下：
*   `src/gpaper/downloader.py`：输入归一化与主入口分流
*   `src/gpaper/semantic_scholar.py`：S2 detail / bulk search / S2 候选探测
*   `src/gpaper/search.py`：DOI 与 title 主链
*   `src/gpaper/sources.py`：arXiv 与各类官方会议渠道
*   `src/gpaper/resolver_support.py`：probe、trace、ResolveRow 等支撑逻辑
*   `src/gpaper/resolver.py`：最终元信息收束与状态判定

### 7. 终端输出状态 (Outputs)
所有的请求最终必定落入以下四种状态之一，并在终端输出统一的结构化摘要（包含标题、DOI、年份、期刊/会议、元数据来源、状态、原因、错误码、下载链接）：
*   ✅ **成功 (Success)**：校验通过，返回 HTTP 200，完整的 PDF 顺利下载。
*   ⏳ **限流等待 (Rate Limited)**：遭遇目标网站或 API 的 429 报错，进入退避重试队列。
*   🔒 **需要人工介入 (Manual Required)**：遭遇 403 / 401 报错，或已知被死死锁定在 IEEE 等必须付费的数据库中。工具会自动为您生成建议的规范文件名，以备手动下载后重命名。
*   ❌ **未找到 (Not Found)**：所有策略和兜底预印本均已穷尽，互联网上确实没有公开版本。

## 🚀 快速开始

### 1. 安装依赖

本项目需要 Python 3.11 或更高版本。

```bash
pip install -r requirements.txt
```

如果后续发布到 PyPI，推荐的安装方式会是：

```bash
pip install gPaper
```

### 2. 配置环境

复制根目录下的 `.env.example` 并重命名为 `.env`，根据需要调整以下配置项以提升解析成功率：

```env
# 核心配置
EXTRACT_REFS_OUTPUT_DIR=./data

# API 凭证 (可选，但强烈建议配置以提升标题/DOI搜索成功率)
EXTRACT_REFS_EMAIL=your_email@example.com
EXTRACT_REFS_S2_API_KEY=your_semantic_scholar_api_key
EXTRACT_REFS_OPENALEX_API_KEY=your_openalex_api_key

# 网络与重试策略
EXTRACT_REFS_TIMEOUT=30
EXTRACT_REFS_RETRIES=2
EXTRACT_REFS_RETRY_WAIT=2
EXTRACT_REFS_RATE_LIMIT_WAIT=20
```

### 3. 运行脚本

您可以选择多种灵活的输入方式来解析并下载论文：

**按 URL 解析并下载：**
```bash
python -m gpaper --url "https://arxiv.org/abs/1711.07971" --title "Non-local Neural Networks" --year 2018 --venue CVPR
```

如果输入的是 arXiv 链接，即使最终下载源仍是 arXiv，程序也会尝试通过 `Semantic Scholar Title Search` 补全正式发表信息，例如 `ICLR`、`CVPR` 等 venue。

**按 DOI 解析并下载：**
```bash
python -m gpaper --doi "10.1109/CVPR.2018.00813" --title "Non-local Neural Networks" --year 2018 --venue CVPR
```

**按标题硬搜并下载：**
```bash
python -m gpaper --name "Mask R-CNN" --year 2017 --venue ICCV
```

安装成命令行工具后，也可以直接这样运行：

```bash
gpaper --name "Mask R-CNN" --year 2017 --venue ICCV
```
