手动添加的url返回的url不限制数量

This commit is contained in:
2026-04-10 14:52:58 +08:00
parent 35d9e5cfc1
commit 06b8116b79
2 changed files with 36 additions and 8 deletions
+10
View File
@@ -47,6 +47,7 @@ type CrawlerConfig struct {
RecrawlMaxAge int `yaml:"recrawl_max_age"` // URL 过期时间(秒),超过此时间的 URL 允许被重爬,默认 30 天 RecrawlMaxAge int `yaml:"recrawl_max_age"` // URL 过期时间(秒),超过此时间的 URL 允许被重爬,默认 30 天
RecrawlCheckInterval int `yaml:"recrawl_check_interval"` // 运行期间检查过期 URL 的间隔(秒),默认 1 小时 RecrawlCheckInterval int `yaml:"recrawl_check_interval"` // 运行期间检查过期 URL 的间隔(秒),默认 1 小时
RecrawlBatchSize int `yaml:"recrawl_batch_size"` // 每次检查最多释放多少个过期 URL,默认 500 RecrawlBatchSize int `yaml:"recrawl_batch_size"` // 每次检查最多释放多少个过期 URL,默认 500
MaxPriorityChildren int `yaml:"max_priority_children"` // priorityChildren 队列的最大链接数,默认 100
} }
// SearchConfig 搜索结果排序权重配置 // SearchConfig 搜索结果排序权重配置
@@ -128,6 +129,7 @@ func GetDefaultConfig() Config {
RecrawlMaxAge: 30 * 86400, // 30 天 RecrawlMaxAge: 30 * 86400, // 30 天
RecrawlCheckInterval: 3600, // 1 小时 RecrawlCheckInterval: 3600, // 1 小时
RecrawlBatchSize: 500, RecrawlBatchSize: 500,
MaxPriorityChildren: 100,
}, },
Search: SearchConfig{ Search: SearchConfig{
UseOnlineSnippet: true, UseOnlineSnippet: true,
@@ -274,5 +276,13 @@ func PromPortBacklink() int { return Global.Prometheus.BacklinkPort }
// PromPortSearch 返回配置值 // PromPortSearch 返回配置值
func PromPortSearch() int { return Global.Prometheus.SearchPort } func PromPortSearch() int { return Global.Prometheus.SearchPort }
// MaxPriorityChildren 返回 priorityChildren 队列的最大链接数(0=不限)。
func MaxPriorityChildren() int {
if Global.Crawler.MaxPriorityChildren <= 0 {
return 100 // 默认 100
}
return Global.Crawler.MaxPriorityChildren
}
// 为了向后兼容,保留 StoragePath 常量 // 为了向后兼容,保留 StoragePath 常量
const StoragePath = "./savedata" const StoragePath = "./savedata"
+26 -8
View File
@@ -240,8 +240,8 @@ func (c *Crawler) runPriorityWorker() {
log.Printf("[crawler] priority crawl started: %s", rawURL) log.Printf("[crawler] priority crawl started: %s", rawURL)
// 直接调用 visitURL,绕过队列调度 // 直接调用 visitURLUnlimited,绕过队列调度和链接数限制
hrefs := c.visitURL(rawURL) hrefs := c.visitURLUnlimited(rawURL)
// 将子链接加入优先队列(保持优先级) // 将子链接加入优先队列(保持优先级)
if len(hrefs) > 0 { if len(hrefs) > 0 {
@@ -436,15 +436,15 @@ func (c *Crawler) Run(entryURL string, maxEpoch int) {
} }
} }
// visitURL 抓取一个 URL,提取关键词、缓存摘要、更新网站元信息,返回页面中发现的子链接。 // visitURLRaw 抓取 URL 的核心逻辑,提取标题、描述、正文、子链接。
func (c *Crawler) visitURL(rawURL string) (hrefs []string) { // 不包含链接数限制,用于优先级爬取。
func (c *Crawler) visitURLRaw(rawURL string) (title, desc, text string, hrefs []string) {
// recover 保护:防止任何模块(analyzer/storage/parser)的 panic 杀死 goroutine // recover 保护:防止任何模块(analyzer/storage/parser)的 panic 杀死 goroutine
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
log.Printf("[crawler] visitURL panic recovered: url=%s error=%v", rawURL, r) log.Printf("[crawler] visitURL panic recovered: url=%s error=%v", rawURL, r)
} }
}() }()
atomic.AddInt64(&c.stats.VisitedURLs, 1) // 计数器 +1
// 使用 sync.WaitGroup + select 实现硬超时包装器, // 使用 sync.WaitGroup + select 实现硬超时包装器,
// 确保即使 http.Client.Timout 被某些底层操作忽略,goroutine 也不会永久阻塞。 // 确保即使 http.Client.Timout 被某些底层操作忽略,goroutine 也不会永久阻塞。
@@ -478,7 +478,7 @@ func (c *Crawler) visitURL(rawURL string) (hrefs []string) {
atomic.AddInt64(&c.stats.SuccessURLs, 1) // 成功计数器 +1 atomic.AddInt64(&c.stats.SuccessURLs, 1) // 成功计数器 +1
// 解析 HTML:提取标题、描述、正文和所有超链接 // 解析 HTML:提取标题、描述、正文和所有超链接
title, desc, text, hrefs := parser.ParseHTML(res.Body, res.FinalURL) title, desc, text, hrefs = parser.ParseHTML(res.Body, res.FinalURL)
// 计算正文内容哈希(FNV-1a),用于增量重爬检测 // 计算正文内容哈希(FNV-1a),用于增量重爬检测
contentHash := fnvHash(text) contentHash := fnvHash(text)
@@ -539,13 +539,31 @@ func (c *Crawler) visitURL(rawURL string) (hrefs []string) {
}) })
} }
return
}
// visitURL 抓取一个 URL,提取关键词、缓存摘要、更新网站元信息,返回页面中发现的子链接。
// 限制返回的链接数,防止下一轮队列爆炸。
func (c *Crawler) visitURL(rawURL string) (hrefs []string) {
atomic.AddInt64(&c.stats.VisitedURLs, 1) // 计数器 +1
_, _, _, hrefs = c.visitURLRaw(rawURL)
// 限制返回的链接数,防止下一轮队列爆炸 // 限制返回的链接数,防止下一轮队列爆炸
if len(hrefs) > 100 { maxLinks := config.MaxPriorityChildren()
hrefs = sampleStrings(hrefs, 100) if maxLinks > 0 && len(hrefs) > maxLinks {
hrefs = sampleStrings(hrefs, maxLinks)
} }
return hrefs return hrefs
} }
// visitURLUnlimited 抓取一个 URL,返回页面中发现的子链接(无链接数限制)。
// 用于手动添加的 Priority URL,保留全部子链接。
func (c *Crawler) visitURLUnlimited(rawURL string) (hrefs []string) {
atomic.AddInt64(&c.stats.VisitedURLs, 1) // 计数器 +1
_, _, _, hrefs = c.visitURLRaw(rawURL)
return hrefs
}
// updateSiteFailure 当某 URL 抓取失败时,更新该网站的访问成功率(指数衰减)。 // updateSiteFailure 当某 URL 抓取失败时,更新该网站的访问成功率(指数衰减)。
func (c *Crawler) updateSiteFailure(rawURL string) { func (c *Crawler) updateSiteFailure(rawURL string) {
host := netloc(rawURL) host := netloc(rawURL)