镜像自地址
https://github.com/lhly/search-syntax-pro.git
已同步 2026-10-20 22:37:48 +08:00
- 添加 DuckDuckGo、Brave、Yandex、Reddit、GitHub 和 StackOverflow 适配器 - 实现动态语言选择器功能 - 更新搜索引擎类型定义和国际化翻译 - 添加详细的搜索引擎文档和语法参考
12 KiB
12 KiB
Yandex 搜索引擎适配器文档
📋 基本信息
| 属性 | 值 |
|---|---|
| 引擎名称 | Yandex |
| 官方网站 | https://yandex.com |
| 市场定位 | 俄罗斯领先搜索引擎 |
| 全球市场份额 | ~2.5% |
| 俄语市场份额 | ~60% (第一名) |
| 主要用户群 | 俄语用户、东欧用户、CIS国家 |
| 优先级 | P1 (中等) |
| 实施复杂度 | 🟡 中等 |
| 预计工期 | 2-3天 |
🎯 产品价值
用户价值
- ✅ 俄语优化: 最佳的俄语搜索体验
- ✅ 区域覆盖: 覆盖俄罗斯、乌克兰、白俄罗斯等
- ✅ 本地化服务: 地图、新闻、邮件等生态系统
- ✅ 独特语法: 支持其他引擎不支持的特殊搜索
业务价值
- 🌍 国际化战略支持
- 📈 扩展非英语市场
- 💡 差异化竞争优势
- 🎯 覆盖特定地域用户群
🔍 支持的搜索语法
1. 基础语法
1.1 网站内搜索 (site:)
关键词 site:域名
示例:
поиск site:wikipedia.org
React site:github.com
说明: 限定搜索结果只来自指定网站
1.2 主机搜索 (host:)
关键词 host:完整主机名
示例:
warming host:www.wikipedia.org
说明: 搜索特定主机上的内容(需要包含www等前缀)
格式: www.second-level-domain.top-level-domain
1.3 反向主机搜索 (rhost:) ⭐ 独有
关键词 rhost:反向域名
示例:
warming rhost:org.wikipedia.www
warming rhost:org.wikipedia.*
说明:
- 使用反向域名格式:
top-level.second-level.www - 支持通配符
*匹配所有子域名 - Yandex独有的特殊语法
用途: 搜索整个域名下的所有子域
1.4 MIME类型搜索 (mime:) ⭐ 独有
关键词 mime:类型
示例:
报告 mime:pdf
数据 mime:xml
图片 mime:image
说明:
- 搜索特定MIME类型的文件
- 比
filetype:更精确 - Yandex独有语法
常用MIME类型:
pdf- PDF文档doc- Word文档xls- Excel文档xml- XML文件image- 所有图片类型
1.5 精确匹配 ("...")
"完整短语"
示例:
"machine learning tutorial"
"React best practices"
2. 逻辑运算符
2.1 AND 运算 (&&)
关键词1 && 关键词2
示例:
Python && tutorial
前端 && 开发
说明: 结果必须同时包含两个关键词
2.2 OR 运算 (|)
关键词1 | 关键词2
示例:
React | Vue
JavaScript | TypeScript
说明: 结果包含任一关键词即可
2.3 必须包含 (+)
+必须包含的词 其他词
示例:
Python +tutorial Flask
说明: +后的词必须出现在结果中
2.4 排除 (-)
关键词 -排除词
示例:
Python -Django
说明: 排除包含指定词的结果
3. 特殊搜索
3.1 日期范围
关键词 date:YYYYMMDD..YYYYMMDD
示例:
新闻 date:20240101..20241231
说明: 搜索指定日期范围内的内容
3.2 标题搜索 (title:)
title:关键词
示例:
title:tutorial React
说明: 只搜索标题中包含关键词的页面
3.3 URL搜索 (url:)
url:关键词
示例:
url:github
url:docs
说明: 只搜索URL中包含关键词的页面
🔧 技术实现
URL 构建格式
基础URL:
https://yandex.com/search/
查询参数:
interface YandexSearchParams {
text: string; // 搜索查询
lr?: number; // 地区ID (如: 213=莫斯科, 2=圣彼得堡)
lang?: string; // 界面语言 (如: 'ru', 'en')
}
完整URL示例:
https://yandex.com/search/?text=React+tutorial+site%3Agithub.com
适配器实现模板
import type { SearchEngineAdapter, SearchParams, SyntaxType, ValidationResult, UIFeatureType } from '@/types'
/**
* Yandex 搜索引擎适配器
* 支持俄语优化和独特的高级搜索语法
*/
export class YandexAdapter implements SearchEngineAdapter {
getName(): string {
return 'Yandex'
}
getBaseUrl(): string {
return 'https://yandex.com/search/'
}
/**
* 构建 Yandex 搜索查询 URL
*/
buildQuery(params: SearchParams): string {
const baseUrl = this.getBaseUrl()
const query = this.buildSearchQuery(params)
const urlParams = new URLSearchParams({
text: query
})
return `${baseUrl}?${urlParams.toString()}`
}
/**
* 构建搜索查询字符串
*/
private buildSearchQuery(params: SearchParams): string {
const queryParts: string[] = []
// 1. 基础关键词
if (params.keyword && params.keyword.trim()) {
queryParts.push(params.keyword.trim())
}
// 2. 精确匹配
if (params.exactMatch && params.exactMatch.trim()) {
queryParts.push(`"${params.exactMatch.trim()}"`)
}
// 3. 网站内搜索
if (params.site && params.site.trim()) {
queryParts.push(`site:${params.site.trim()}`)
}
// 4. MIME类型搜索 (Yandex独有)
if (params.fileType && params.fileType.trim()) {
queryParts.push(`mime:${params.fileType.trim()}`)
}
// 5. 标题搜索
if (params.inTitle && params.inTitle.trim()) {
queryParts.push(`title:${params.inTitle.trim()}`)
}
// 6. URL搜索
if (params.inUrl && params.inUrl.trim()) {
queryParts.push(`url:${params.inUrl.trim()}`)
}
// 7. 日期范围
if (params.dateRange) {
const { from, to } = params.dateRange
if (from && to) {
const fromDate = this.formatDate(from)
const toDate = this.formatDate(to)
queryParts.push(`date:${fromDate}..${toDate}`)
}
}
// 8. 排除关键词
if (params.excludeWords && params.excludeWords.length > 0) {
params.excludeWords.forEach(word => {
if (word.trim()) {
queryParts.push(`-${word.trim()}`)
}
})
}
// 9. OR 逻辑关键词 (使用 | 符号)
if (params.orKeywords && params.orKeywords.length > 0) {
const orQuery = params.orKeywords
.filter(word => word.trim())
.join(' | ')
if (orQuery) {
queryParts.push(`(${orQuery})`)
}
}
return queryParts.join(' ')
}
/**
* 格式化日期为 YYYYMMDD
*/
private formatDate(dateString: string): string {
const date = new Date(dateString)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}${month}${day}`
}
/**
* 验证语法类型
*/
validateSyntax(syntax: SyntaxType): boolean {
const supportedSyntax: SyntaxType[] = [
'site',
'filetype', // 实际使用 mime:
'exact',
'intitle',
'inurl',
'exclude',
'or',
'date_range'
]
return supportedSyntax.includes(syntax)
}
/**
* 获取支持的语法类型
*/
getSupportedSyntax(): SyntaxType[] {
return [
'site',
'filetype',
'exact',
'intitle',
'inurl',
'exclude',
'or',
'date_range'
]
}
/**
* 获取支持的UI功能特性
*/
getSupportedFeatures(): UIFeatureType[] {
return [
'site',
'filetype',
'exact_match',
'intitle',
'inurl',
'exclude',
'or_keywords',
'date_range'
]
}
/**
* 验证搜索参数
*/
validateParams(params: SearchParams): ValidationResult {
const errors: string[] = []
const warnings: string[] = []
// 检查基本关键词
if (!params.keyword || !params.keyword.trim()) {
if (!params.exactMatch && !params.site) {
errors.push('请输入搜索关键词')
}
}
// 检查日期范围
if (params.dateRange) {
if (params.dateRange.from && params.dateRange.to) {
const fromDate = new Date(params.dateRange.from)
const toDate = new Date(params.dateRange.to)
if (fromDate > toDate) {
errors.push('开始日期不能晚于结束日期')
}
}
}
return {
isValid: errors.length === 0,
errors,
warnings
}
}
/**
* 获取搜索建议
*/
getSearchSuggestions(params: SearchParams): string[] {
const suggestions: string[] = []
if (params.keyword && !params.site) {
suggestions.push('使用 site: 可以在特定网站内搜索')
}
if (params.fileType) {
suggestions.push('Yandex使用mime:语法进行文件类型搜索')
}
if (params.keyword && !params.dateRange) {
suggestions.push('可以使用日期范围筛选最新内容')
}
return suggestions
}
}
📝 实施清单
Phase 1: 核心功能 (Day 1)
- 创建
src/services/adapters/yandex.ts - 实现
YandexAdapter类 - 实现基础语法 (site, mime, exact)
- 单元测试
Phase 2: 高级功能 (Day 2)
- 实现逻辑运算符 (&&, |, +, -)
- 实现日期范围搜索
- 实现 title: 和 url: 语法
- 参数验证
Phase 3: 特殊功能 (Day 3)
- 实现 rhost: 反向域名搜索(可选)
- 实现 host: 主机搜索(可选)
- UI集成和国际化
- 完整测试
✅ 测试用例
describe('YandexAdapter', () => {
const adapter = new YandexAdapter()
test('基础关键词搜索', () => {
const url = adapter.buildQuery({
keyword: 'React tutorial',
engine: 'yandex'
})
expect(url).toContain('text=React+tutorial')
})
test('MIME类型搜索', () => {
const url = adapter.buildQuery({
keyword: '报告',
fileType: 'pdf',
engine: 'yandex'
})
expect(url).toContain('mime%3Apdf')
})
test('日期范围搜索', () => {
const url = adapter.buildQuery({
keyword: '新闻',
dateRange: {
from: '2024-01-01',
to: '2024-12-31'
},
engine: 'yandex'
})
expect(url).toContain('date%3A20240101..20241231')
})
test('OR逻辑运算', () => {
const url = adapter.buildQuery({
keyword: 'tutorial',
orKeywords: ['React', 'Vue'],
engine: 'yandex'
})
expect(url).toContain('React+%7C+Vue')
})
test('组合查询', () => {
const url = adapter.buildQuery({
keyword: 'programming',
site: 'github.com',
inTitle: 'tutorial',
excludeWords: ['beginner'],
engine: 'yandex'
})
expect(url).toContain('site%3Agithub.com')
expect(url).toContain('title%3Atutorial')
expect(url).toContain('-beginner')
})
})
🌍 国际化支持
{
"engines.yandex": "Yandex",
"engines.yandex.description": "俄罗斯领先的搜索引擎",
"engines.yandex.features": {
"mime": "MIME类型搜索",
"rhost": "反向域名搜索",
"host": "主机搜索",
"russian": "俄语优化"
},
"engines.yandex.tips": {
"mime": "使用mime:而非filetype:进行文件搜索",
"rhost": "rhost:可以搜索整个域名的所有子域",
"operators": "支持 && (AND) 和 | (OR) 逻辑运算"
}
}
📚 参考资源
官方文档
⚠️ 特殊说明
rhost: 语法使用示例
搜索整个Wikipedia域名:
关键词 rhost:org.wikipedia.*
只搜索www.wikipedia.org:
关键词 rhost:org.wikipedia.www
MIME vs filetype
| Yandex (mime:) | 标准 (filetype:) |
|---|---|
mime:pdf |
filetype:pdf |
mime:image |
filetype:jpg |
mime:xml |
filetype:xml |
建议: UI层将 filetype: 转换为 mime: 以适配Yandex
🔄 更新日志
| 日期 | 版本 | 更新内容 |
|---|---|---|
| 2025-11-09 | v1.0 | 初始文档创建,包含独特语法支持 |
下一步: 查看 Reddit 文档 了解社区搜索引擎的实现细节