使用Go Colly多规则抓取多站点作者标签并写入CSV的问题
解决Go Colly多站点作者标签抓取与变量赋值问题
1. 修复"author_name declared and not used"错误
你的错误根源是在if代码块内使用了:=声明变量,这会创建一个局部变量,和外层的author_name不是同一个变量。外层变量不会被更新,且局部变量未被使用,因此触发编译错误。
修正方法:将if内的:=改为赋值操作=,直接更新外层已声明的author_name变量:
c.OnHTML("body", func(e *colly.HTMLElement) { author_name := e.DOM.Find("div.author").Text() if author_name == "" { // 改用=赋值,而非:=声明新变量 author_name = e.DOM.Find("p.author").Text() } if author_name == "" { log.Println("Author not found") } author := Authors{ Author: author_name, } articleCollection = append(articleCollection, author) })
2. 多标签优先级抓取优化
如果需要支持更多类型的作者标签(如span.author、h3.author等),可以定义一个选择器优先级列表,循环尝试直到找到非空结果:
c.OnHTML("body", func(e *colly.HTMLElement) { var author_name string // 定义优先级从高到低的选择器列表 selectors := []string{"div.author", "p.author", "span.author", "h3.author"} for _, sel := range selectors { author_name = e.DOM.Find(sel).Text() if author_name != "" { break // 找到结果后跳出循环 } } if author_name == "" { log.Println("Author not found") } author := Authors{ Author: author_name, } articleCollection = append(articleCollection, author) })
3. 结合正则表达式筛选灵活标签
如果需要匹配类名包含author的任意标签(如div.author-info、p.post-author),可以用GoQuery的FilterFunction结合正则实现:
import "regexp" // 预编译正则表达式,匹配类名包含author的元素 var authorClassRegex = regexp.MustCompile(`author`) c.OnHTML("body", func(e *colly.HTMLElement) { var author_name string // 遍历所有元素,筛选类名匹配正则的元素 e.DOM.Find("*").FilterFunction(func(i int, s *goquery.Selection) bool { class, exists := s.Attr("class") return exists && authorClassRegex.MatchString(class) }).Each(func(i int, s *goquery.Selection) { if author_name == "" { author_name = s.Text() } }) if author_name == "" { log.Println("Author not found") } author := Authors{ Author: author_name, } articleCollection = append(articleCollection, author) })
4. 导出结果到CSV文件
完成抓取后,可使用Go标准库encoding/csv将结果导出:
import ( "encoding/csv" "os" ) func exportToCSV(authors []Authors) error { file, err := os.Create("authors.csv") if err != nil { return err } defer file.Close() writer := csv.NewWriter(file) defer writer.Flush() // 写入表头 if err := writer.Write([]string{"Author Name"}); err != nil { return err } // 写入数据 for _, a := range authors { if err := writer.Write([]string{a.Author}); err != nil { return err } } return nil } // 在抓取完成后调用: // c.Wait() // exportToCSV(articleCollection)
内容的提问来源于stack exchange,提问作者Maxim Zhukotsky
相关产品推荐
相关产品推荐

