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

使用Golang的Colly库实现点击按钮/展开下拉菜单功能的方法

Colly实现动态页面交互操作的解决方案

首先明确结论:Colly本身不支持直接模拟点击按钮、触发JS事件这类浏览器交互行为。Colly的定位是轻量级静态HTTP爬虫,仅会下载目标URL的原始HTML响应,不会执行页面内嵌的JavaScript,也没有浏览器的DOM渲染、事件触发能力,无法直接完成下拉菜单展开、点击触发内容更新这类动态操作。

你可以根据目标站点的反爬强度选择以下两种可行方案:

方案1:抓包构造接口请求(优先推荐)

点击按钮触发页面内容更新的本质,是页面JS在交互后发起了对应的AJAX/Fetch请求拉取新数据,你可以直接抓包拿到这个接口的请求规则,用Colly直接发起请求获取数据,效率远高于模拟浏览器操作。
操作步骤:

  • 打开浏览器开发者工具的「网络」面板,点击对应按钮/下拉菜单,过滤XHR/Fetch类型的请求,找到返回目标更新内容的接口
  • 分析接口的请求方法、请求头、参数(包括Query参数、请求体、Cookie、CSRF Token等校验字段,如果有加密参数需要逆向对应JS逻辑生成)
  • 用Colly构造和浏览器请求完全一致的请求,直接获取返回数据,JSON格式直接解析,HTML片段可以用Colly自带的HTML解析能力提取字段
    示例代码:
package main

import (
	"fmt"
	"net/http"

	"github.com/gocolly/colly/v2"
)

func main() {
	// 初始化采集器
	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"),
	)

	// 先访问初始页面,获取Cookie、CSRF Token等必要校验参数
	var csrfToken string
	c.OnHTML("meta[name=csrf-token]", func(e *colly.HTMLElement) {
		csrfToken = e.Attr("content")
	})

	c.OnScraped(func(r *colly.Response) {
		// 构造点击按钮对应的接口请求
		apiCollector := c.Clone()
		apiCollector.OnResponse(func(resp *colly.Response) {
			fmt.Println("接口返回内容:", string(resp.Body))
			// 这里可以做后续的数据提取逻辑
		})
		// 发起接口请求,带上所有必要的头和参数
		err := apiCollector.Request(
			"POST",
			"https://目标站点/点击后调用的接口地址",
			nil,
			nil,
			http.Header{
				"X-CSRF-Token":     []string{csrfToken},
				"X-Requested-With": []string{"XMLHttpRequest"},
				"Content-Type":     []string{"application/x-www-form-urlencoded"},
			},
		)
		if err != nil {
			panic(err)
		}
	})

	// 访问初始页面
	c.Visit("https://目标站点/初始页面地址")
}

方案2:结合无头浏览器实现模拟交互

如果目标站点接口加密逻辑复杂,无法直接构造请求,可以把Colly和Go生态的无头浏览器库搭配使用:用无头浏览器完成模拟点击、页面渲染的操作,拿到完整的渲染后HTML,再交给Colly做数据解析提取。
常用的Go无头浏览器库有chromedp、rod两种,示例基于chromedp实现:

package main

import (
	"context"
	"fmt"

	"github.com/chromedp/chromedp"
	"github.com/gocolly/colly/v2"
)

func main() {
	// 初始化无头浏览器上下文
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	var renderedHTML string
	// 执行模拟交互逻辑
	err := chromedp.Run(ctx,
		chromedp.Navigate("https://目标站点/初始页面地址"),
		// 等待下拉菜单按钮加载完成
		chromedp.WaitVisible(`#dropdown-btn`, chromedp.ByID),
		// 模拟点击展开下拉菜单
		chromedp.Click(`#dropdown-btn`, chromedp.ByID),
		// 等待目标选项加载完成
		chromedp.WaitVisible(`.option-item`, chromedp.ByQuery),
		// 模拟点击对应选项
		chromedp.Click(`.option-item:nth-child(2)`, chromedp.ByQuery),
		// 等待内容更新区域加载完成
		chromedp.WaitVisible(`#content-area`, chromedp.ByID),
		// 拿到完整渲染后的页面HTML
		chromedp.OuterHTML("html", &renderedHTML),
	)
	if err != nil {
		panic(err)
	}

	// 将渲染后的HTML交给Colly解析
	c := colly.NewCollector()
	c.OnHTML("#content-area", func(e *colly.HTMLElement) {
		// 提取目标字段
		fmt.Println("提取到的更新内容:", e.Text)
	})
	// 解析HTML内容
	c.ParseHTML(renderedHTML)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:48:03