You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go使用colly爬取数据时如何在GraphQL Resolver返回完整Article数组

问题修复方案

问题原因

  • 回调函数内部新建了局部切片articleModel,完全没有操作外部声明的articles变量,最终返回的切片自然为空
  • 你开启了colly.Async()异步模式,OnHTML的回调会在独立的goroutine中执行,直接对切片做append操作是非并发安全的,即使你写入外部切片也可能出现数据丢失

修复后代码

import "sync"

// 原有Article结构体定义保持不变
type Article struct {
    Title     string `bson:"title"`
    Source    string `bson:"source"`
    Url       string `bson:"url"`
    Timestamp string `bson:"timestamp"`
}

func (r *RootResolver) News() ([]models.Article, error) {
    c := colly.NewCollector(
        colly.MaxDepth(2),
        colly.Async(),
    )

    c.Limit(&colly.LimitRule{Parallelism: 10})

    articles := []models.Article{}
    var mu sync.Mutex // 新增互斥锁保证并发写入安全

    c.OnHTML("article", func(e *colly.HTMLElement) {
        article := models.Article{
            Title:     e.ChildText("h3 a"),
            Source:    e.ChildText("a[data-n-tid]"),
            Timestamp: e.ChildAttr("div:last-child time", "datetime"),
            // 可选优化:如果拿到的是相对路径,可转成绝对路径
            // Url: e.Request.AbsoluteURL(e.ChildAttr("a[href]", "href")),
            Url: e.ChildAttr("a[href]", "href"),
        }
        // 加锁后写入外部切片
        mu.Lock()
        articles = append(articles, article)
        mu.Unlock()
    })

    c.Visit(SOMEURLHERE)
    c.Wait()

    return articles, nil
}

核心修改说明

  • 移除回调内局部的articleModel切片,直接构造单个Article实例
  • 新增sync.Mutex互斥锁,每次写入articles切片前加锁,写入完成后解锁,避免并发写入导致的数据异常
  • 将构造好的文章实例追加到外部声明的articles切片中,爬取到的数据就会被正常保留到返回结果里

内容的提问来源于stack exchange,提问作者user16663541

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:45:03