GO 学习 二 [爬虫实战]

        本文讲解 使用Go进行爬虫,其实做爬虫Python可能更好一点,语言简洁第三方库多,当然这里是为了加深对GO语言的理解和使用,所有使用GO进行爬虫,算是一种经验积累。

GO 语言请求库

        做爬虫 肯定需要请求对应的网址,拿到对应的链接内容进行相对应的解析,这里需要用到对应的库

        go 语言中,net/http 是一个内置的库,用于构建 HTTP 客户端和服务器

1. 客户端

  • 发送 HTTP 请求:使用 http.Gethttp.Posthttp.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/muxchi/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.ModeDiros.ModePerm来设置目录的默认权限,这通常是0777

perm := os.ModeDir | os.ModePerm

写入截图:

 

结果截图:

        

结语:

        本次分享到这,注意下图片存储路径最好给绝对路径,可能是作者这边的环境问题吧,出了个问题给相对路径运行不出结果,改成绝对路径就ok了,ok就说到这儿,各位大佬加油!

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值