Metadata-Version: 2.4
Name: kwtree
Version: 0.1.0
Summary: 精细化搜索关键词组合生成工具
Author-email: Chandler <275737875@qq.com>
License-Expression: MIT
Keywords: search,keyword,generator,university,surname
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
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: click>=8.0.0
Requires-Dist: rich>=12.0.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: xlsxwriter>=3.0.0
Requires-Dist: llmdog>=0.0.3

# kwtree：精细化搜索关键词组合生成工具

kwtree 是一个强大的命令行工具和 Python 库，用于基于学校排名和百家姓数据生成精细化搜索关键词组合。支持多种生成模式、LLM 智能优化、自定义数据加载和多格式输出。

## 功能特性

1. **三种生成模式**：支持 `university`（学校）、`surname`（百家姓）、`both`（两者组合）三种搜索词扩展方向
2. **丰富的内置数据**：内置 C9、985、211 等 11 个学校分类（300+ 高校），以及 500+ 传统百家姓和 90+ 现代高频姓氏
3. **LLM 智能优化**：通过 llmdog 库调用大模型，自动去除不合理组合、补充遗漏搜索词
4. **多格式输出**：支持 txt 文本文件（UTF-8 编码）和 Excel 文件（.xlsx）两种输出格式
5. **自定义数据加载**：支持导出内置 YAML 数据，编辑后通过 `--uni-yaml` / `--surname-yaml` 加载自定义配置
6. **频率阈值过滤**：百家姓模式支持按最小频率百分比筛选姓氏，精准控制搜索词数量
7. **拼音扩展**：百家姓模式可选生成拼音形式搜索词，扩大搜索覆盖范围
8. **跨分类去重**：学校模式自动按名称去重，避免同一学校在不同分类中重复出现
9. **Rich 终端美化**：使用 Rich 库输出结构化表格、状态面板和彩色错误提示，提升用户体验
10. **跨平台兼容**：支持 Python 3.9+，Windows 平台自动处理 UTF-8 编码输出

## 安装和环境配置

### 环境要求

- Python 3.9 或更高版本
- 操作系统：Windows / macOS / Linux

### 安装步骤



**从 PyPI 安装**（如果已发布）：

```bash
pip install kwtree
```

**验证安装**：

```bash
kw --version
```

### LLM API Key 配置（可选）

如果需要使用 LLM 优化功能，请配置环境变量：

```bash
# Linux / macOS
export LLM_API_KEY="your-api-key-here"

# Windows (命令提示符)
set LLM_API_KEY=your-api-key-here

# Windows (PowerShell)
$env:LLM_API_KEY="your-api-key-here"
```

### Windows UTF-8 编码说明

kwtree 在 Windows 平台下会自动重配置 stdout/stderr 为 UTF-8 编码，确保中文搜索词正确输出。无需额外配置。

## 使用示例和代码片段

### 命令行使用

#### 1. 搜索词生成（search 命令）

**基础用法**：生成"字节"相关的学校和百家姓搜索词

```bash
kw search 字节
```

**指定模式和分类**：仅生成 C9 高校相关搜索词

```bash
kw search 字节 --mode university --categories c9
```

**多分类组合**：生成 985 和 211 高校搜索词（自动去重）

```bash
kw search 腾讯 --mode university --categories 985 211
```

**百家姓模式**：使用 top50 高频姓氏，包含拼音

```bash
kw search 阿里 --mode surname --source top50 --include-pinyin
```

**频率阈值过滤**：仅保留频率 >= 2.0 的姓氏

```bash
kw search 美团 --mode surname --min-frequency 2.0
```

**双模式组合**：同时生成学校和百家姓搜索词

```bash
kw search 字节 --mode both --categories c9 --source top50 --include-pinyin
```

**LLM 优化**：启用大模型优化搜索词

```bash
kw search 字节 --mode both --use-llm
```

**Excel 输出**：生成 Excel 格式文件

```bash
kw search 字节 --format excel -o result.xlsx
```

**自定义数据**：加载自定义学校和百家姓 YAML 文件

```bash
kw search 字节 --uni-yaml my_config/universities.yaml --surname-yaml my_config/surnames.yaml
```

**仅终端输出**：不写入文件

```bash
kw search 字节 --no-output
```

#### 2. 数据导出（dump 命令）

**导出全部内置数据**：

```bash
kw dump all -o my_config/
```

**仅导出学校数据**：

```bash
kw dump universities -o my_config/
```

**仅导出百家姓数据**：

```bash
kw dump surnames -o my_config/
```

导出后可编辑 YAML 文件，然后通过 `--uni-yaml` / `--surname-yaml` 参数加载。

#### 3. 数据浏览（list-categories 命令）

**查看内置学校分类**：

```bash
kw list-categories
```

**查看自定义学校分类**：

```bash
kw list-categories --uni-yaml my_config/universities.yaml
```

输出示例：
```
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 分类               ┃ 高校数量     ┃ 示例（前3所）                  ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ c9                 │ 9            │ 北京大学, 清华大学, 复旦大学... │
│ 985                │ 39           │ 北京大学, 清华大学, 复旦大学... │
│ 211                │ 50           │ 北京大学, 清华大学, 复旦大学... │
│ us_top100          │ 20           │ Harvard University, MIT...      │
└────────────────────┴──────────────┴────────────────────────────────┘
```

#### 4. 姓氏列表（list-surnames 命令）

**查看 top50 高频姓氏**：

```bash
kw list-surnames
```

**查看传统百家姓**：

```bash
kw list-surnames --source baijiaxing --limit 100
```

**查看自定义姓氏数据**：

```bash
kw list-surnames --surname-yaml my_config/surnames.yaml
```

### Python API 使用

#### 基础示例

```python
from keyword_tree import (
    load_universities,
    load_surnames,
    generate_keywords,
    write_txt,
    write_excel,
)

# 加载内置数据
uni_data = load_universities()
surname_data = load_surnames()

# 生成搜索词
keywords = generate_keywords(
    keyword="字节",
    mode="both",
    uni_data=uni_data,
    surname_data=surname_data,
    categories=["c9"],
    surname_source="top50",
    include_pinyin=True,
)

# 写入文件
write_txt(keywords, "result.txt", header="字节搜索词")
write_excel(keywords, "result.xlsx")
```

#### 自定义数据加载

```python
# 加载自定义学校数据
uni_data = load_universities(yaml_path="my_config/universities.yaml")

# 加载自定义百家姓数据
surname_data = load_surnames(yaml_path="my_config/surnames.yaml")

# 生成搜索词
keywords = generate_keywords(
    keyword="腾讯",
    mode="university",
    uni_data=uni_data,
    surname_data=surname_data,
    categories=["my_company"],  # 自定义分类
)
```

#### LLM 优化

```python
from keyword_tree import optimize_keywords

# 生成原始搜索词
keywords = generate_keywords(...)

# 使用 LLM 优化（前 50 条）
optimized_keywords = optimize_keywords(keywords, max_count=50)
```

#### 函数调用模式（不写入文件）

```python
from keyword_tree import load_universities, load_surnames, generate_keywords

# 仅返回搜索词列表
uni_data = load_universities()
surname_data = load_surnames()

keywords = generate_keywords(
    keyword="阿里",
    mode="surname",
    uni_data=uni_data,
    surname_data=surname_data,
    min_frequency=2.0,
)

# 直接在代码中使用
for kw in keywords:
    print(kw)
```

## API 接口说明

### 核心函数

#### 1. `generate_keywords()`

生成搜索词列表

**参数**：
- `keyword` (str)：核心关键词（如"字节"、"腾讯"）
- `mode` (str)：生成模式，必须为 `"university"`、`"surname"` 或 `"both"`
- `uni_data` (dict)：学校数据字典
- `surname_data` (dict)：百家姓数据字典
- `categories` (list[str] | None)：学校分类列表，为 None 时使用全部分类
- `surname_source` (str)：姓氏数据来源，`"baijiaxing"` 或 `"top50"`，默认 `"top50"`
- `min_frequency` (float | None)：最小频率阈值，仅保留 `frequency >= 此值` 的姓氏
- `include_pinyin` (bool)：是否同时生成拼音形式，默认 False

**返回值**：`list[str]`，搜索词列表，格式为 `"{关键词} {扩展项}"`

**异常**：
- `ValueError`：mode 参数无效

**示例**：
```python
keywords = generate_keywords(
    keyword="字节",
    mode="university",
    uni_data=uni_data,
    surname_data=surname_data,
    categories=["c9"],
)
# 返回：["字节 北京大学", "字节 清华大学", ...]
```

#### 2. `load_universities()`

加载学校排名数据

**参数**：
- `yaml_path` (str | None)：自定义 YAML 文件路径，为 None 时使用内置数据

**返回值**：`dict`，学校数据字典

**数据结构**：
```python
{
    "c9": [
        {
            "name": "北京大学",
            "pinyin": "Peking University",  # 可选
            "alias": ["北大", "PKU"]        # 可选
        },
        ...
    ],
    "985": [...],
    ...
}
```

**异常**：
- `FileNotFoundError`：YAML 文件不存在
- `yaml.YAMLError`：YAML 格式错误
- `ValueError` / `KeyError`：数据结构不匹配

#### 3. `load_surnames()`

加载百家姓数据

**参数**：
- `yaml_path` (str | None)：自定义 YAML 文件路径，为 None 时使用内置数据

**返回值**：`dict`，百家姓数据字典

**数据结构**：
```python
{
    "baijiaxing": [
        {
            "surname": "王",
            "pinyin": "Wang",
            "frequency": 7.41,
            "notable": ["王安石", "王羲之"]  # 可选
        },
        ...
    ],
    "top50": [...],
}
```

**异常**：
- `FileNotFoundError`：YAML 文件不存在
- `yaml.YAMLError`：YAML 格式错误
- `ValueError` / `KeyError`：数据结构不匹配

#### 4. `optimize_keywords()`

使用 LLM 优化搜索词列表

**参数**：
- `keywords` (list[str])：原始搜索词列表
- `max_count` (int)：发送给 LLM 的最大数量，默认 50

**返回值**：`list[str]`，优化后的搜索词列表。如果 LLM 调用失败，返回原始列表

**异常**：无（内部捕获所有异常并回退）

#### 5. `write_txt()`

将搜索词列表写入 txt 文件

**参数**：
- `keywords` (list[str])：搜索词列表
- `filepath` (str)：输出文件路径
- `header` (str | None)：可选的头部说明文字

**返回值**：`str`，写入的文件路径

**文件格式**：
```
头部说明（如有）
========================================
搜索词1
搜索词2
...
```

#### 6. `write_excel()`

将搜索词列表写入 Excel 文件

**参数**：
- `keywords` (list[str])：搜索词列表
- `filepath` (str)：输出文件路径（.xlsx）

**返回值**：`str`，写入的文件路径

**Excel 结构**：
- Sheet 名称："搜索词"
- A 列：序号（从 1 开始）
- B 列：搜索词
- 自动调整列宽

### 数据约束

#### 高校条目（University Entry）
- `name` (str)：学校全称，**必填**，不可为空
- `pinyin` (str)：学校名称拼音，选填
- `alias` (list[str])：学校别名/缩写列表，选填

#### 学校分类（University Category）
- 分类键：YAML 顶层键，字符串（如 "c9"、"985"、"211"）
- 分类值：高校条目列表，至少包含 1 个条目
- 跨分类重复：同一学校可出现在多个分类中，生成搜索词时按名称去重

#### 姓氏条目（Surname Entry）
- `surname` (str)：姓氏汉字，**必填**，不可为空
- `pinyin` (str)：姓氏拼音，**必填**，首字母大写（如 "Wang"）
- `frequency` (float)：人口频率百分比，**必填**，取值范围 [0, 100]
- `notable` (list[str])：知名人物列表，选填

## 依赖项清单

| 依赖库 | 最低版本 | 作用说明 |
|--------|---------|----------|
| click | >=8.0.0 | CLI 框架，用于构建命令行接口 |
| rich | >=12.0.0 | 终端美化，输出表格、面板和彩色文本 |
| pyyaml | >=6.0 | YAML 解析，加载学校和百家姓数据 |
| xlsxwriter | >=3.0.0 | Excel 文件写入（仅 `--format excel` 需要） |
| llmdog | >=0.1.0 | LLM 调用库（仅 `--use-llm` 需要） |

**可选依赖**：
- `xlsxwriter`：如果仅使用 txt 输出，可不安装此库
- `llmdog`：如果不需要 LLM 优化功能，可不安装此库

## 贡献指南与许可证信息

### 代码规范

1. 遵循 PEP 8 编码规范
2. 使用类型注解（Type Hints）提高代码可读性
3. 所有公开函数必须包含文档字符串（Docstring）
4. 错误信息使用中文，便于国内用户理解

### 提交流程

1. Fork 本仓库
2. 创建特性分支（`git checkout -b feature/AmazingFeature`）
3. 提交更改（`git commit -m 'Add some AmazingFeature'`）
4. 推送到分支（`git push origin feature/AmazingFeature`）
5. 提交 Pull Request

### 开发环境搭建

```bash
# 安装开发依赖
pip install -r requirements.txt
pip install -e .

# 运行测试（如果有）
pytest
```

### 许可证

本项目采用 [MIT License](LICENSE) 开源协议。

### 联系方式

- 项目主页：https://github.com/your-org/kwtree
- 问题反馈：https://github.com/your-org/kwtree/issues

---

**kwtree** v1.0.0 · 让搜索词生成更高效、更智能
