gogcli 实战:使用 `gog youtube search` 在终端中搜索 YouTube 视频、频道与播放列表
gogcli 实战:使用 gog youtube search 在终端中搜索 YouTube 视频、频道与播放列表
gog youtube search 是 gogcli(Google Workspace in your terminal)内置的 YouTube Data API 命令组,用于在终端中直接检索视频、频道与播放列表,无需打开浏览器。本文以命令参考文档为骨架,结合仓库源码与测试用例,完整讲解命令用法、全部参数、认证方式与输出格式,帮助你将其无缝接入脚本与自动化工作流。
命令概览与定位
gog youtube search 属于 gog youtube 命令组,与 activities、videos、playlists、comments、channels、subscriptions 等子命令并列,负责"搜索"这一入口功能。在源码中,该命令定义于 internal/cmd/youtube.go,帮助信息为 "Search YouTube for videos, channels, or playlists"。
从源码结构看,gog youtube search 本身是一个命令容器(有别名 find),实际执行搜索的是其唯一子命令 list:
gog youtube (yt) search (find) <command>
| 子命令 | 说明 |
|---|---|
| gog youtube search list | Search for videos, channels, or playlists(别名 ls) |
使用前准备:配置 YouTube API Key 或 OAuth 账号
搜索命令在未指定账号时走 API Key 通道(源码见 internal/cmd/youtube_services.go 的 getYouTubeAPIKey 与 getYouTubeServiceWithAPIKey)。若未配置密钥,命令会报错:
YouTube API key required: set config youtube_api_key KEY or GOG_YOUTUBE_API_KEY
API Key 的配置有两种方式(配置实现见 internal/config/keys.go):
# 方式一:环境变量(优先级更高,配置 Get 逻辑优先读取)
export GOG_YOUTUBE_API_KEY=your_key
# 方式二:写入 gogcli 配置(该 key 被标记为 Sensitive,存储时会做敏感处理)
gog config set youtube_api_key your_key
# 验证配置
gog config get youtube_api_key
如果通过 -a/--account 或环境变量 GOG_ACCOUNT 指定了账号(即存在"账号选择器"),getYouTubeReadService(internal/cmd/youtube.go)会自动切换到 OAuth 账号通道,走 youtube.force-ssl 等 OAuth 作用域,此时不再需要 API Key。
gog youtube search list:执行一次搜索
搜索入口是 gog youtube search list(别名 ls),完整用法:
gog youtube (yt) search (find) list (ls) <query> [flags]
查询词是位置参数,必须提供且不能为空。源码 internal/cmd/youtube.go 的 Run 方法在 query 为空时直接返回 usage("search query is required")。
搜索专用参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--type |
string |
video |
资源类型:video、channel、playlist,支持逗号分隔多选 |
--order |
string |
relevance |
排序方式:relevance、date、rating、title、videoCount、viewCount |
--channel-id |
string |
将结果限定到指定频道 | |
--max--limit |
int64 |
25 |
单页最大结果数 |
--page |
string |
分页令牌(来自上一页输出的 nextPageToken) |
各参数的校验规则在源码中均有明确实现:
- 类型校验:
splitCSV(c.Type)拆解逗号分隔值后,逐项校验必须是video/channel/playlist之一,否则报错--type must be video, channel, or playlist (comma-separated); - 数量上限:
validateYouTubeMax(internal/cmd/youtube.go)要求--max在 1~50 之间,超出报错--max must be between 1 and 50; - 排序枚举:
--order字段声明了enum:"relevance,date,rating,title,videoCount,viewCount",传入非法值会被命令行解析器直接拒绝。
完整示例
# 默认按相关性搜索视频
gog youtube search list "golang tutorials"
# 使用别名:find + ls,搜索频道并按订阅数排序
gog yt find ls "go programming" --type channel --order videoCount --max 5
# 同时搜索视频与播放列表
gog youtube search list "docker tutorial" --type video,playlist
# 限定在某个频道内搜索
gog youtube search list "kubernetes" --type video --channel-id UC_x5XG1OV2P6uZZ5FSM9Ttw
# 翻页:拿到上一页的 nextPageToken 后继续
gog youtube search list "terraform" --page CAUQAA
# 输出 JSON 供脚本消费
gog youtube search list "openai" --json
表格输出列说明
非 JSON 模式下,结果以表格输出。列定义见 internal/cmd/youtube_presentation.go 的 youtubeSearchColumns:
| 列 | 含义 |
|---|---|
KIND |
资源类型:video、channel、playlist |
ID |
对应资源的 ID(VideoId/ChannelId/PlaylistId 之一) |
TITLE |
标题 |
CHANNEL |
所属频道标题 |
PUBLISHED_AT |
发布时间 |
当无结果时,命令会向 stderr 输出 No results 并以成功状态退出(便于脚本判断空结果,不会触发错误码)。若还有后续页,会打印 nextPageToken 提示。
源码级原理:一次搜索请求的内部链路
在 internal/cmd/youtube.go 中,搜索最终映射为 YouTube Data API v3 的 search.list 调用:
call := svc.Search.List([]string{"snippet"}).
Q(query).
Type(types...).
Order(c.Order).
MaxResults(c.Max).
PageToken(c.Page)
if channelID := strings.TrimSpace(c.ChannelID); channelID != "" {
call = call.ChannelId(channelID)
}
resp, err := call.Do()
值得注意的实现细节是:请求发出后,Run 还会调用 filterYouTubeSearchItemsByType(internal/cmd/youtube.go)对返回结果做一次本地二次过滤——根据每个 SearchResult 的 Id 字段实际携带的是 VideoId、ChannelId 还是 PlaylistId 来判定类型,剔除与 --type 不匹配的意外结果。这是对 API 返回数据的兜底校验,也是 KIND 列取值的来源(类型判定逻辑见 internal/cmd/youtube.go 的 youtubeSearchResultType)。
输出层统一走 internal/outfmt 包:JSON 模式输出 {"items": [...], "nextPageToken": "..."} 信封结构;普通模式调用 outfmt.WriteTable 输出上述六列表格。
认证模式选择:API Key 还是 OAuth?
搜索命令的认证选择逻辑集中在前文提到的 getYouTubeReadService:
- 未指定账号(无
-a、无GOG_ACCOUNT、无--access-token):使用 API Key(internal/cmd/youtube.go 的youtubeAccountSelectorPresent判定); - 指定了账号或 access token:要求先完成
gog auth add登录,然后使用 OAuth 账号通道。
这一行为有对应测试覆盖:internal/cmd/youtube_test.go 的 TestYouTubeSearchWithAPIKey 验证了 API Key 通道下请求会携带 q=golang+tutorials、type=channel、order=videoCount 等查询参数;同文件的 TestYouTubeSearchWithOAuth、TestYouTubeSearchWithAutoAccountUsesOAuthService 则验证了账号选择器存在时切换到 OAuth 服务;TestYouTubeSearchFiltersUnexpectedKinds 验证了本地类型过滤逻辑。
全局 Flags:搜索命令可用的通用选项
gog youtube search 及其子命令继承全部全局 Flags(与仓库中其他命令一致,均由 gog schema --json 生成)。下表为完整清单:
| Flag | 类型 | 默认值 | 说明 |
|---|---|---|---|
--access-token |
string |
直接使用提供的 access token(绕过已存储的 refresh token;token 约 1 小时过期) | |
-a--account--acct |
string |
账号邮箱、别名或 auto,用于需要认证的 Google API 命令 | |
--client |
string |
OAuth 客户端名称(选择已存储的凭据与令牌桶) | |
--color |
string |
auto |
颜色输出:auto|always|never |
--disable-commands |
string |
逗号分隔的禁用命令列表,支持点路径 | |
-n--dry-run--dryrun--noop--preview |
bool |
不执行变更,打印预期动作后成功退出 | |
--enable-commands |
string |
逗号分隔的启用命令前缀列表(限制 CLI 范围) | |
--enable-commands-exact |
string |
逗号分隔的精确启用命令列表,父命令不会连带启用子命令 | |
-y--force--assume-yes--yes |
bool |
跳过破坏性命令的确认 | |
--gmail-no-send |
bool |
false |
阻止 Gmail 发送操作(Agent 安全选项) |
-h--help |
kong.helpFlag |
显示上下文相关帮助 | |
--home |
string |
覆盖 gogcli 配置/数据/状态/缓存根目录(等价于 GOG_HOME) |
|
-j--json--machine |
bool |
false |
向 stdout 输出 JSON(最适合脚本化) |
--no-input--non-interactive--noninteractive |
bool |
永不提示,失败即退出(适合 CI) | |
-p--plain--tsv |
bool |
false |
输出稳定的可解析文本(TSV,无颜色) |
--quota-project |
string |
用于计费的 Google Cloud 项目(作为 X-Goog-User-Project 发送;部分 API 在 --access-token/ADC 模式下需要) |
|
--readonly |
bool |
false |
运行时阻止变更类 API 请求;auth add 时也仅请求只读 OAuth scope |
--results-only |
bool |
JSON 模式下只输出主结果(丢弃 nextPageToken 等信封字段) |
|
--select--pick--project |
string |
JSON 模式下选择逗号分隔字段(尽力而为,支持点路径;多数命令建议使用 --fields) |
|
-v--verbose |
bool |
开启详细日志 | |
--version |
kong.VersionFlag |
打印版本并退出 | |
--wrap-untrusted |
bool |
false |
JSON/raw 输出中,将抓取的文本字段包裹在外部不可信内容标记中 |
在脚本与 CI 中的典型组合
# 脚本友好:JSON 输出 + 只取主要结果 + 非交互
gog youtube search list "grpc tutorial" --json --results-only --no-input
# 终端人类可读:TSV 输出,便于 grep/awk
gog youtube search list "grpc tutorial" --plain | awk -F'\t' '{print $2, $3}'
# 只读安全模式(搜索本身只读,此处用于一致性约束)
gog youtube search list "grpc tutorial" --readonly
搜索后的下一步:将结果接入其他 youtube 命令
搜索返回的 ID 可以直接喂给 gog youtube 命令组中的其他子命令,形成终端内的完整工作流。例如,先用 search 拿到视频 ID,再用 gog youtube videos list 查看详情,或用 gog youtube playlists items list 检查播放列表内容;搜索到频道后,可配合 gog youtube channels list 查看订阅数、视频数与总观看数,也可以结合 gog youtube playlists list --channel-id 列出该频道的所有播放列表。
由于所有命令都支持 --json 与 --plain 两种机器可读输出,你可以把搜索、翻页、详情查询串成一行管道或 shell 函数,无需离开终端即可完成从"搜索"到"深挖"的完整链路。
总结
gog youtube search 是 gogcli 访问 YouTube Data API 的"检索门户":一个位置参数加 --type/--order/--channel-id 三个核心筛选参数,即可覆盖视频、频道、播放列表三类资源的搜索;结合 --max、--page 翻页与 --json/--plain 输出,天然适合脚本化。其底层直接映射 search.list 接口,并额外实现了客户端二次类型过滤与 1~50 的结果数校验,行为可由仓库测试(internal/cmd/youtube_test.go)逐一验证。在使用前,请确保已通过 GOG_YOUTUBE_API_KEY 环境变量或 gog config set youtube_api_key 配置 API Key;需要账号级数据时,则用 gog auth add 完成 OAuth 登录并通过 -a 指定账号。