Metadata-Version: 2.4
Name: liepin-cat
Version: 0.1.0
Summary: 猎聘简历搜索与查看工具
Author-email: Chandler <275737875@qq.com>
License-Expression: MIT
Keywords: liepin,resume,search,crawler
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24.0
Requires-Dist: openpyxl>=3.1.0
Requires-Dist: typer>=0.9.0
Requires-Dist: rich>=13.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"

# liepin-cat

猎聘简历搜索与查看工具 - 一个用于检索和查看猎聘平台简历数据的 Python 库和命令行工具。

## 功能特性

- **关键词搜索**: 支持自定义关键词检索猎聘平台简历
- **自动翻页**: 智能分页采集,支持最大页数限制
- **数据导出**: 自动保存 JSON 中间结果,导出扁平化 Excel 表格
- **简历查看**: 查看单条简历完整详情或批量批量查看
- **双重接口**: 同时支持 CLI 命令行和 Python API 调用
- **会话管理**: 自动加载 cookies,懒加载 HTTP 客户端
- **容错处理**: 批量处理时单条失败不影响整体流程

## 环境要求

- Python >= 3.9
- 有效的猎聘平台 cookies.json 文件

## 安装说明

### 1. 安装 liepin-cat 包

```bash
pip install liepin-cat
```

### 2. 验证安装

```bash
liepin --help
```

## 快速开始

### 准备 cookies.json

从浏览器导出猎聘平台的 cookies:

1. 登录猎聘网站 (https://www.liepin.com)
2. 打开浏览器开发者工具 (F12)
3. 进入 Application/存储 -> Cookies
4. 找到 api-lpt.liepin.com 域名的所有 cookies
5. 导出为 JSON 格式,保存为 `cookies.json`

**支持的格式:**

格式一 - 浏览器导出格式 (列表):
```json
[
  {"name": "cookie_name_1", "value": "cookie_value_1"},
  {"name": "cookie_name_2", "value": "cookie_value_2"}
]
```

格式二 - 简单字典格式:
```json
{
  "cookie_name_1": "cookie_value_1",
  "cookie_name_2": "cookie_value_2"
}
```

### 基本使用流程

```bash
# 1. 搜索简历
liepin search "Google Engineer"

# 2. 查看单条简历(从搜索结果获取 resIdEncode)
liepin resume "f7eb207597Ddbca39845b9b" --sk "ee095100-7526-4554-a649-fa701f6840aa"

# 3. 批量查看简历
liepin batch-resume search_results.json
```

## CLI 命令详解

### search 命令 - 搜索简历

搜索简历并导出为 JSON 和 Excel 格式。

**用法:**
```bash
liepin search [OPTIONS] KEYWORD
```

**必选参数:**
- `KEYWORD`: 搜索关键词,如 "阿里巴巴 总监"

**可选参数:**
- `-c, --cookies PATH`: cookies.json 文件路径 (默认: cookies.json)
- `-p, --max-pages INT`: 最大翻页数 (默认: 100)
- `-j, --json PATH`: JSON 结果保存路径 (默认: search_results.json)
- `-e, --excel PATH`: Excel 输出路径 (默认: search_results.xlsx)

**示例:**
```bash
# 使用默认配置搜索
liepin search "Python 开发"

# 指定 cookies 文件和最大页数
liepin search "Java 架构师" -c /path/to/cookies.json -p 50

# 自定义输出文件名
liepin search "产品经理" -j results.json -e results.xlsx

# 不保存 JSON,只生成 Excel
liepin search "数据分析师" -j ""
```

### resume 命令 - 查看简历详情

查看单条简历的完整详情。

**用法:**
```bash
liepin resume [OPTIONS] RES_ID_ENCODE
```

**必选参数:**
- `RES_ID_ENCODE`: 简历编码 ID (从搜索结果获取)

**可选参数:**
- `-c, --cookies PATH`: cookies.json 文件路径
- `--sk TEXT`: searchKey
- `--ck TEXT`: ck
- `--fk TEXT`: filterKey
- `--position TEXT`: 位置序号
- `--jobtitle-code TEXT`: 职位编码
- `--sss TEXT`: sss 校验值
- `--s-scene TEXT`: 搜索场景标识
- `-o, --output PATH`: 输出 JSON 文件路径 (不指定则输出到终端)

**示例:**
```bash
# 查看简历详情并输出到终端
liepin resume "f7eb207597Ddbca39845b9b"

# 保存简历详情到文件
liepin resume "f7eb207597Ddbca39845b9b" -o resume_detail.json

# 使用完整的上下文参数(推荐,成功率更高)
liepin resume "f7eb207597Ddbca39845b9b" \
  --sk "ee095100-7526-4554-a649-fa701f6840aa" \
  --ck "ee095100-7526-4554-a649-fa701f6840aa" \
  --fk "ee095100-7526-4554-a649-fa701f6840aa" \
  --position "1" \
  --jobtitle-code "job123" \
  --sss "abc123" \
  --s-scene "search"
```

### batch-resume 命令 - 批量查看简历

从搜索结果 JSON 文件批量查看简历详情。

**用法:**
```bash
liepin batch-resume [OPTIONS] SEARCH_JSON
```

**必选参数:**
- `SEARCH_JSON`: 搜索结果 JSON 文件路径 (由 search 命令生成)

**可选参数:**
- `-c, --cookies PATH`: cookies.json 文件路径
- `-o, --output-dir PATH`: 简历详情输出目录 (默认: resumes)

**示例:**
```bash
# 批量查看并保存到默认目录
liepin batch-resume search_results.json

# 指定输出目录
liepin batch-resume search_results.json -o my_resumes

# 指定 cookies 文件
liepin batch-resume search_results.json -c /path/to/cookies.json
```

## Python API 使用

### 基础示例

```python
from liepin import LiepinSession, Search, Resume

# 创建会话并搜索
with LiepinSession("cookies.json") as session:
    # 搜索简历
    search = Search(session)
    results = search.search("阿里巴巴 总监", max_pages=10)
    
    # 导出为 Excel
    Search.to_excel(results, "output.xlsx")
    
    # 查看单条简历
    if results:
        resume = Resume(session)
        first_item = results[0]
        detail = resume.view_from_search_result(first_item)
        print(detail)
```

### 高级用法

```python
from liepin import LiepinSession, Search, Resume
import json

# 自定义搜索流程
with LiepinSession("cookies.json") as session:
    search = Search(session)
    
    # 搜索但不保存 JSON
    results = search.search(
        keyword="Python 高级工程师",
        max_pages=5,
        save_json=None  # 不保存中间 JSON
    )
    
    print(f"共获取 {len(results)} 条结果")
    
    # 手动保存到自定义位置
    if results:
        with open("custom_results.json", "w", encoding="utf-8") as f:
            json.dump(results, f, ensure_ascii=False, indent=2)

# 查看简历详情
with LiepinSession("cookies.json") as session:
    resume = Resume(session)
    
    # 方式一: 手动指定参数
    detail = resume.view(
        res_id_encode="f7eb207597Ddbca39845b9b",
        sk="ee095100-7526-4554-a649-fa701f6840aa"
    )
    
    # 方式二: 从搜索结果自动提取(推荐)
    # detail = resume.view_from_search_result(search_result_item)
    
    # 保存到文件
    with open("resume.json", "w", encoding="utf-8") as f:
        json.dump(detail, f, ensure_ascii=False, indent=2)
```

### 批量处理示例

```python
import json
from pathlib import Path
from liepin_cat import LiepinSession, Resume

# 加载搜索结果
with open("search_results.json", "r", encoding="utf-8") as f:
    results = json.load(f)

# 创建输出目录
output_dir = Path("resumes")
output_dir.mkdir(exist_ok=True)

# 批量查看简历
with LiepinSession("cookies.json") as session:
    resume = Resume(session)
    
    success_count = 0
    fail_count = 0
    
    for idx, item in enumerate(results, 1):
        res_id = item.get("resIdEncode", f"unknown_{idx}")
        print(f"[{idx}/{len(results)}] 处理: {res_id}")
        
        try:
            detail = resume.view_from_search_result(item)
            output_file = output_dir / f"{res_id}.json"
            output_file.write_text(
                json.dumps(detail, ensure_ascii=False, indent=2),
                encoding="utf-8"
            )
            success_count += 1
        except Exception as e:
            print(f"  失败: {e}")
            fail_count += 1
    
    print(f"\n完成! 成功: {success_count}, 失败: {fail_count}")
```

## 数据格式说明

### 搜索结果 JSON 结构

```json
[
  {
    "resIdEncode": "f7eb207597Ddbca39845b9b",
    "userName": "张三",
    "sk": "ee095100-7526-4554-a649-fa701f6840aa",
    "ck": "ee095100-7526-4554-a649-fa701f6840aa",
    "fk": "ee095100-7526-4554-a649-fa701f6840aa",
    "position": "1",
    "jobtitleCode": "job123",
    "sss": "abc123",
    "sScene": "search",
    "searchHiliteKeys": [["Python", "开发"]],
    "cvBaseInfo": {
      "userName": "张三",
      "sex": "男",
      "age": 30
    }
  }
]
```

### Excel 输出格式

搜索结果导出为 Excel 时,嵌套字段会被扁平化:

| resIdEncode | cvBaseInfo.userName | cvBaseInfo.sex | cvBaseInfo.age | searchHiliteKeys |
|-------------|---------------------|----------------|----------------|------------------|
| f7eb2075... | 张三 | 男 | 30 | [["Python", "开发"]] |

**扁平化规则:**
- 嵌套字典: 使用点号分隔 (如 `cvBaseInfo.userName`)
- 列表字段: 序列化为 JSON 字符串
- 空值: 转为空字符串

## 最佳实践

### 1. 合理使用翻页限制

```bash
# 小范围测试
liepin search "关键词" -p 5

# 确认结果满意后再扩大范围
liepin search "关键词" -p 50
```

### 2. 定期保存中间结果

搜索过程会自动保存 JSON 中间文件,即使中断也不会丢失已获取的数据。

### 3. 批量查看时添加延迟

为避免请求过于频繁,可在 Python API 中添加延迟:

```python
import time

for item in results:
    detail = resume.view_from_search_result(item)
    time.sleep(1)  # 每次请求间隔 1 秒
```

### 4. 错误处理

```python
try:
    results = search.search("关键词")
except Exception as e:
    print(f"搜索失败: {e}")
    # 检查 cookies 是否有效、网络是否正常
```

## 注意事项

### 安全提醒

1. **保护 cookies.json**: 该文件包含您的登录凭证,请勿提交到版本控制系统或分享给他人
2. **定期更新 cookies**: cookies 会过期,需要定期从浏览器重新导出
3. **使用 HTTPS**: 所有请求均使用 HTTPS 协议,确保数据传输安全

### 合规使用

1. **遵守平台规则**: 请确保您的使用行为符合猎聘平台的服务条款
2. **控制请求频率**: 避免短时间内大量请求,建议添加适当的延迟
3. **合理使用数据**: 获取的数据仅用于合法用途,不得用于侵犯隐私或其他不当行为

### 技术限制

1. **翻页上限**: 默认最大 100 页,防止无限翻页
2. **请求超时**: 单次请求超时时间为 30 秒
3. **空页终止**: 遇到空结果页会立即停止翻页
4. **cookies 格式**: 必须为有效的 JSON 格式,支持列表和字典两种格式

### 常见问题

**Q: 提示 "cookies 文件不存在"?**
A: 确保 cookies.json 文件在当前目录,或使用 `-c` 参数指定完整路径。

**Q: 搜索结果为空?**
A: 检查关键词是否正确,或尝试更换关键词;同时确认 cookies 是否有效。

**Q: 批量查看时部分失败?**
A: 这是正常现象,某些简历可能因权限或其他原因无法查看。工具会跳过失败项继续处理。

**Q: 如何更新 cookies?**
A: 重新从浏览器导出最新的 cookies.json 文件,覆盖旧文件即可。

## 开发指南

### 安装开发依赖

```bash
pip install -e ".[dev]"
```

### 代码格式化

```bash
black src/ tests/
ruff check src/ tests/
```

### 运行测试

```bash
pytest tests/ -v
```

## 项目结构

```
liepin/
├── pyproject.toml          # 项目配置和依赖
├── README.md               # 本文档
├── .gitignore              # Git 忽略配置
├── src/
│   └── liepin/
│       ├── __init__.py     # 包入口
│       ├── session.py      # 会话管理模块
│       ├── search.py       # 搜索模块
│       ├── resume.py       # 简历查看模块
│       └── cli.py          # CLI 命令行入口
└── tests/                  # 测试目录
```

## 技术栈

- **httpx**: 现代化 HTTP 客户端,支持异步和同步
- **openpyxl**: Excel 文件读写
- **typer**: 基于类型提示的 CLI 框架
- **rich**: 终端美化和彩色输出

## 许可证

MIT License


## 免责声明

本工具仅供学习和研究使用,使用者需自行承担使用风险和责任。开发者不对因使用本工具造成的任何损失或法律后果负责。请遵守相关法律法规和平台使用条款。
