常见错误是调用http.Get后未读取resp.Body,导致页面内容为空;必须用io.ReadAll(resp.Body)显式读取并及时Close,同时检查StatusCode、设置Client超时、处理Content-Type编码及反爬头。

用 http.Get 发起请求但没读取响应体,页面内容为空
常见错误是调用 http.Get 后直接打印 resp 或忽略 resp.Body,结果得到空字符串。HTTP 响应体是流式数据,必须显式读取,且读完后需关闭 Body 防止连接泄漏。
- 务必用
io.ReadAll(resp.Body)或bufio.NewReader(resp.Body).ReadBytes('\n')等方式读取全部内容 - 读取前检查
resp.StatusCode,非 2xx 状态码(如 404、503)时Body仍可能有错误 HTML,不能跳过 - 读完立即调用
resp.Body.Close(),否则连接会堆积,高并发下易触发too many open files
http.Client 超时设置不生效,请求卡死几十秒
默认的 http.DefaultClient 没有超时控制,遇到 DNS 慢、服务器无响应等情况会阻塞很久。必须自定义 http.Client 并设置 Timeout 或更细粒度的 Transport 参数。
- 简单场景用
&http.Client{Timeout: 10 * time.Second}即可覆盖连接、响应头、响应体读取全过程 - 需要区分控制时,改用
Transport:设置DialContext控制建连、ResponseHeaderTimeout控制 header 接收、ReadBufferSize影响吞吐(尤其大 HTML) - 注意:超时时间包含重定向跳转耗时,若目标站频繁 302,实际请求可能远超设定值
中文乱码(显示为 或空白),不是编码问题而是没处理 Content-Type
很多网页的 Content-Type 响应头带 charset=utf-8 或 gbk,但 Go 的 http.Response 不自动解码。直接把字节切片当 UTF-8 字符串打印,遇到 GBK 编码就会出错。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 优先从
resp.Header.Get("Content-Type")解析 charset,例如text/html; charset=gb2312→ 提取gb2312 - 用
golang.org/x/net/html/charset包自动识别并转换:charset.NewReaderLabel(charsetLabel, bodyBytes),它能 fallback 到 meta 标签或 HTML5 算法 - 别硬写
strings.ToValidUTF8(string(bodyBytes)),这只会掩盖问题,无法还原原始中文
被反爬拦截,返回 403 或空白页,User-Agent 不是唯一原因
只加 User-Agent 头大概率仍被拒绝。现代反爬会校验 Accept、Accept-Language、Referer,甚至检查 TLS 握手指纹和 HTTP/2 支持。
立即学习“go语言免费学习笔记(深入)”;
- 基础伪装至少补全:
Accept: text/html,application/xhtml+xml、Accept-Language: zh-CN,zh、Referer: https://www.google.com/ - 避免使用默认
http.Transport,它禁用 HTTP/2;启用需设ForceAttemptHTTP2: true(Go 1.12+ 默认开启,但某些旧服务依赖 HTTP/1.1 头行为) - 如果目标站用 Cloudflare 或 JS 挑战,纯 HTTP 请求必然失败——这时候不是代码问题,是技术路线错了
真正难的不是“怎么发请求”,而是判断该不该发、发了之后怎么信。比如 Content-Type 缺失时该猜 utf-8 还是 gb18030?重定向链里某次跳转返回 500,要不要继续?这些没有标准答案,得看目标站点的实际响应模式。


















