本文讲解 使用Go进行爬虫,其实做爬虫Python可能更好一点,语言简洁第三方库多,当然这里是为了加深对GO语言的理解和使用,所有使用GO进行爬虫,算是一种经验积累。
GO 语言请求库
做爬虫 肯定需要请求对应的网址,拿到对应的链接内容进行相对应的解析,这里需要用到对应的库
go 语言中,
net/http
是一个内置的库,用于构建 HTTP 客户端和服务器1. 客户端
- 发送 HTTP 请求:使用
http.Get
、http.Post
、http.NewRequest
等函数来发送 GET、POST 等 HTTP 请求。- 读取 HTTP 响应:从返回的
*http.Response
对象中读取响应体、状态码、响应头等。示例:发送 GET 请求
package main import ( "fmt" "net/http" ) resp, err := http.Get("http://example.com") fmt.Println(resp, err) if err != nil { // 处理错误 } defer resp.Body.Close() // 处理响应体
2. 服务器
- 设置路由:通常与第三方库(如
gorilla/mux
、chi/chi
等)结合使用来设置路由。但net/http
本身也提供了基本的路由功能(如http.HandleFunc
)。- 处理请求:定义处理器函数来处理各种 HTTP 方法(GET、POST 等)。
- 中间件:虽然
net/http
没有直接提供中间件的概念,但可以通过包装处理器函数来实现类似的功能。- 文件服务:使用
http.FileServer
来提供静态文件服务。示例:简单的 HTTP 服务器
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Path) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
3. 方法
http.Get(url string) (*Response, error)
:发送 GET 请求。http.Post(url, contentType string, body io.Reader) (*Response, error)
:发送 POST 请求。http.NewRequest(method, url string, body io.Reader) (*Request, error)
:创建一个新的请求。http.HandleFunc(pattern string, handler func(ResponseWriter, *Request))
:注册一个处理函数到默认的 ServeMux。http.ListenAndServe(addr string, handler Handler) error
:在指定的地址和端口上启动 HTTP 服务器。http.FileServer(root FileSystem) Handler
:返回一个使用给定文件系统的Handler
。
地址:aHR0cHM6Ly9tLmR1aXRhbmcuY29tL25hcGkvYmxvZy9saXN0L2J5X3NlYXJjaC8/c3RhcnQ9MjQmbGltaXQ9MjQmbW9yZT0xJl9fZG9tYWluPXd3dy5kdWl0YW5nLmNvbSZpbmNsdWRlX2ZpZWxkcz1zZW5kZXIlMkNhbGJ1bSUyQ2xpa2VfY291bnQlMkNtc2cma3c9JUU1JThBJUE4JUU2JUJDJUFC
直接上代码和截图
package main
import (
"fmt"
"github.com/tidwall/gjson"
"io/ioutil"
"net/http"
"strings"
)
// 全局定义图片路径
var images_path = "D:\\JetBrains\\Project\\GO\\crawl\\images\\"
/*
method: ProcessingRequests
PS:处理请求地址
params: url 请求地址
params: filePath 图片存储路径
*/
func ProcessingRequests(url string, filePath string) {
client := &http.Client{}
req, reqErr := http.NewRequest("GET", url, nil)
if reqErr != nil {
fmt.Println("NewRequest======>", reqErr)
}
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")
resp, resErr := client.Do(req)
if resErr != nil {
fmt.Println("Do Request======>", resErr)
}
defer resp.Body.Close() // 确保在函数返回前关闭响应体
//fmt.Println("response Body======>", resp.Body)
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
fmt.Println("Read Body======>", readErr)
}
JsonString := string(body)
// 取 图片对象json内容
var objectList = gjson.Get(JsonString, "data").Get("object_list").Array()
for _, obj := range objectList {
covers := obj.Get("album").Get("covers").Array()[0].String()
coverName := strings.Split(covers, "/")
//fmt.Println("coverName", coverName[7], len(coverName))
photo := obj.Get("photo").Get("path").String()
photoName := strings.Split(photo, "/")
//fmt.Println("photoName", photoName[7], len(photoName))
//fmt.Println(covers, photo)
urls := [2]string{covers, photo}
fileNames := [2]string{coverName[7], photoName[7]}
for index := range fileNames {
imageName, reqUrl := fileNames[index], urls[index]
// 创建文件下载对象
imgRes, img_ := http.Get(reqUrl)
downloadMsg := "当前图片请求的下载地址|链接:%s,图片名称:%s\n"
fmt.Printf(downloadMsg, reqUrl, imageName)
if img_ != nil {
fmt.Println("下载过程中请求失败", reqUrl)
}
defer imgRes.Body.Close()
// 创建图片文件,写入内容
body, err := ioutil.ReadAll(imgRes.Body)
if err != nil {
fmt.Println(err)
}
_ = ioutil.WriteFile(filePath+imageName, body, 0755)
}
}
}
func main() {
// 构建url地址请求
url := "加密地址的api"
// 2 10
for crawlNum := 1; crawlNum <= 10; crawlNum++ {
reqUrl := fmt.Sprintf(url, crawlNum*24) + "api的params参数"
ProcessingRequests(reqUrl, images_path)
}
}
关于写入文件的权限整理:
设置所有用户的读权限:
perm := os.FileMode(0644)
设置所有用户的写权限:
perm := os.FileMode(0222)
设置所有用户的执行权限:
perm := os.FileMode(0111)
设置所有用户的读写执行权限:
perm := os.FileMode(0777)
只为文件所有者设置读写执行权限,其他用户只有读权限:
perm := os.FileMode(0744)
只为文件所有者设置读写执行权限,组用户和其他用户只有读和执行权限:
perm := os.FileMode(0755)
使用
os.ModePerm
来设置默认的文件权限,这通常是0666
:perm := os.ModePerm
结合
os.ModeDir
和os.ModePerm
来设置目录的默认权限,这通常是0777
:perm := os.ModeDir | os.ModePerm
写入截图:
结果截图:
结语:
本次分享到这,注意下图片存储路径最好给绝对路径,可能是作者这边的环境问题吧,出了个问题给相对路径运行不出结果,改成绝对路径就ok了,ok就说到这儿,各位大佬加油!