golang以及python爬虫实际上都是访问网站后获取返回的数据包(html),使用正则或者xpath获取对应标签中的内容,但golang的高并发加上chan协助能够以更快的速度完成任务,相比较而言python爬虫更加快速
package main
import (
“fmt”
“io”
“net/http”
“regexp”
“strconv”
)
func httprequest(url string) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
buf := make([]byte, 4096)
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
result += string(buf[:n])
}
return
}
func apge(i int, page chan int) {
url := “https://tieba.baidu.com/f?kw=%E5%92%8C%E5%B9%B3%E7%B2%BE%E8%8B%B1&ie=utf-8&pn=” + strconv.Itoa((i-1)*50)
result, err := httprequest(url)
if err != nil {
fmt.Printf("请求失败\n")
return
}
reg := regexp.MustCompile("<b>(.*)</b>")//正则表达式
pinglun := reg.FindAllStringSubmatch(result, -1)
for _, name := range pinglun {
fmt.Printf("你选择的输出值为\n")
fmt.Print(name[1])
fmt.Printf("\n")
}
f, err := os.Create("第" + strconv.Itoa(i) + "页" + ".html")
if err != nil {
fmt.Print("创建文件失败")
}
f.WriteString(result)
f.Close()
page <- i
}
func woroking(start, end int) {
fmt.Printf(“你的起始页数为%d,你的终止页数为%d\n”, start, end)
if end < start {
fmt.Print(“输出值应该大于输入值”)
}
page := make(chan int)
for i := start; i < end; i++ {
go apge(i, page)
}
for i := start; i < end; i++ {
fmt.Printf("正在写入%d个数据", <-page)
}
}
func main() {
var (
start int
end int
)
fmt.Println("输入你想爬取的起始页数")
fmt.Scanln(&start)
fmt.Println("输入你想爬取的终止页数")
fmt.Scanln(&end)
woroking(start, end)
}
这是一段以贴吧为例简单的爬虫代码,并发也就是通过不断地运行一个新的方法进行执行,使用chan进行协助,避免主方法提前结束,使用不同工具编写go会有一些小区别,
以下是我编写过程中出现的问题
main函数有红色下划线,原因:在相同目录下存在两个go文件导致,新建一个文件夹,将其中一个转入到新建文件夹即可
永真方法:对for或者if方法的进程或者返回值要判断清楚,否则会出现永真方法
strconv.Itoa()转化为字符串类型进行拼接
chan函数为协助,避免主程序提前结束导致方法无法执行
鼠标放到对应方法中可以看到具体的利用方法,以及是否返回err