goquery爬取script标签内容写文件为空,如何修正代码?
goquery爬虫内容可打印但文件写入为空问题修复方案
问题根因
- 选择器匹配规则过于宽松:原代码
doc.Find("script")匹配页面所有script标签,且仅判断是否存在type属性,未校验type值是否为目标的myjson,导致匹配到无内容的无关script标签 - 文件写入逻辑存在覆盖问题:循环内每次匹配到符合条件的标签都会调用
os.Create,该方法会直接清空目标路径已有文件内容,先写入的空内容会覆盖后续有效内容,或后续内容写入被异常中断
修复方案
方案1:使用精准属性选择器(推荐)
goquery支持CSS属性选择器,可直接定位到type="myjson"的目标script标签,无需遍历所有标签,代码更简洁高效:
// 直接精准匹配目标script标签 targetScript := doc.Find(`script[type="myjson"]`).First() if targetScript.Length() == 0 { panic("未找到目标myjson标签") } content := targetScript.Text() // 确认内容非空再写入文件 if content != "" { filepath := "mypath" file, err := os.Create(filepath) if err != nil { panic("COULD NOT CREATE FILE") } // 写入内容 _, err = file.WriteString(content) if err != nil { panic("写入文件失败") } // 主动刷缓存到磁盘 _ = file.Sync() file.Close() fmt.Println(content) }
方案2:修正原有遍历逻辑的判断条件
如果需要保留遍历逻辑,可在原有判断中新增type值校验,同时避免循环内重复创建覆盖同一文件:
var targetContent string doc.Find("script").Each(func(i int, element *goquery.Selection) { typeVal, exists := element.Attr("type") // 同时校验type存在且值为myjson if exists && typeVal == "myjson" { targetContent = element.Text() // 找到目标后可提前终止遍历 return } }) if targetContent == "" { panic("未找到有效内容") } // 统一执行文件写入逻辑 filepath := "mypath" file, err := os.Create(filepath) if err != nil { panic("COULD NOT CREATE FILE") } defer file.Close() _, err = file.WriteString(targetContent) if err != nil { panic("写入文件失败") } _ = file.Sync() fmt.Println(targetContent)
注意事项
- 尽量使用
defer file.Close()保证文件句柄正常关闭,避免资源泄漏 - 写入后调用
file.Sync()主动将内存缓存写入磁盘,避免操作系统缓存延迟导致的文件空内容问题 - 匹配到内容后再执行文件创建逻辑,避免空内容覆盖有效文件
内容的提问来源于stack exchange,提问作者Lorenzo Romani
相关产品推荐
相关产品推荐

