
本文详解 Go 爬虫程序编译成功却无法执行的根本原因:误用 string(count) 将整数转为字符串,导致 URL 构造失败、HTTP 请求 404、文件写入空名,最终程序“看似运行实则无效果”。
本文详解 go 网络爬虫程序编译成功却无法执行的根本原因:误用 string(count) 将整数转为字符串,导致 url 构造失败、http 请求 404、文件写入空名,最终程序“看似运行实则无效果”。
Go 是一门强类型语言,string(count) 并非将整数 count 转为十进制字符串,而是将其视为 Unicode 码点(rune),强制转换为对应字符。例如 string(1) 得到的是不可见的 SOH 控制字符(U+0001),string(49) 才是 '1'。因此以下代码:
adrr := string("http://torhit.com/torbite/?page=" + string(count))实际生成的 URL 类似于 "http://torhit.com/torbite/?page=\x01"(而非 ?page=1),服务端无法识别该路径,返回 404 或空响应;同时 ioutil.WriteFile("scrap.txt"+string(count), ...) 会尝试写入如 scrap.txt\x01 这类非法/不可见文件名,在多数系统中可能静默失败或覆盖同名文件。
✅ 正确做法是使用标准库 strconv 包进行数值格式化:
package main
import (
"io/ioutil"
"net/http"
"strconv" // ✅ 必须导入
"time"
)
func excuter(count int) {
// ✅ 正确:将 int 转为字符串
url := "http://torhit.com/torbite/?page=" + strconv.Itoa(count)
resp, err := http.Get(url)
if err != nil {
// ❗务必检查错误,避免静默失败
return
}
defer resp.Body.Close() // ✅ 推荐 defer,更安全
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
// ✅ 文件名使用合法数字字符串
filename := "scrap.txt" + strconv.Itoa(count)
ioutil.WriteFile(filename, bytes, 0644) // ⚠️ 0777 权限过高,建议 0644
}
func main() {
const maxcount = 200
// ✅ 启动 goroutine 后需等待完成,否则主函数退出,所有 goroutine 被强制终止
done := make(chan struct{}, maxcount)
for count := 1; count <= maxcount; count++ {
go func(c int) {
excuter(c)
done <- struct{}{}
}(count)
}
// ✅ 等待全部完成
for i := 0; i < maxcount; i++ {
<-done
}
}⚠️ 关键注意事项:
- 不要忽略错误:http.Get 和 ioutil.ReadAll 的错误必须显式处理,否则失败无提示;
- goroutine 生命周期管理:原代码 main() 启动 200 个 goroutine 后立即结束,整个进程退出,所有并发任务被强制中止——这是“不执行”的另一主因;
- 资源释放:使用 defer resp.Body.Close() 比手动调用更可靠;
- 权限安全:文件模式 0777 赋予全局可执行权限,存在安全隐患,静态内容推荐 0644;
- 并发控制:生产环境应限制并发数(如用 semaphore 或 worker pool),避免对目标站点造成过大压力或触发封禁。
总结:Go 中整数 → 字符串必须用 strconv.Itoa() 或 fmt.Sprintf("%d", n);同时,任何并发程序都需显式同步生命周期。二者缺一,都将导致“编译通过却毫无效果”的典型陷阱。


















