Go colly爬虫框架精简高效【杠杠的】入门到精通

1 前言

1.1 Go Colly 爬虫介绍

爬虫框架中,各中流行的编程语言都有自己热门框架,python中的selenium、Scrapy、PySpider等,Java中的Nutch、Crawler4j、WebMagic、WebCollector等。golang中colly使用Go语言编写的功能强大的爬虫框架,api简洁、性能强大、并发性高,github star 接近20K。

1.2 安装

go init colly.demo
go get -u github.com/gocolly/colly/v2

1.3 hello word

入门程序:抓取百度首页的按钮文字:“百度一下”

package main

import (
	"fmt"
	"log"

	"github.com/gocolly/colly/v2"
)

func main() {
	// 创建收集器
	c := colly.NewCollector()

	// 获取 "百度一下" 按钮文本
	c.OnHTML("#su", func(e *colly.HTMLElement) {
		baiduBtn := e.Attr("value")
		fmt.Println(baiduBtn)
	})

	// 开始访问
	err := c.Visit("http://www.baidu.com/")
	if err != nil {
		log.Fatalln(err)
		return
	}
}

PS D:\dev\go\workspace\go-colly-demo> go run .\demo1.go
百度一下

2 使用介绍

2.1 核心生命周期函数介绍

  • NewCollector 创建收集器对象
  • Visit 开始访问
  • OnRequest 请求发起时回调,一般用来设置请求头等
  • OnHTML 匹配指定元素后回调
  • OnXML 和OnHTML类似,用于匹配xpath解析
  • OnScraped 在所有OnHTML之后执行,可以用来做一些回收操作
  • OnError 请求发生错误回调,比如404
package main

import (
	"fmt"
	"log"

	"github.com/gocolly/colly/v2"
)

func main() {
	// 创建收集器
	c := colly.NewCollector()

	// 匹配指定元素后回调
	c.OnHTML("#su", func(e *colly.HTMLElement) {
		baiduBtn := e.Attr("value")
		fmt.Println("匹配到目标元素ID su:", baiduBtn)
	})

	// 可以多次 OnHTML 不同的页面元素
	c.OnHTML("#kw", func(e *colly.HTMLElement) {
		maxlength := e.Attr("maxlength")
		fmt.Println("匹配到目标元素ID kw, 最多允许输入:", maxlength)
	})

	// 请求发起时回调,一般用来设置请求头等
	c.OnRequest(func(request *colly.Request) {
		fmt.Println("----> 开始请求了")
	})

	// 请求完成后回调
	c.OnResponse(func(response *colly.Response) {
		fmt.Println("----> 开始返回了")
	})

	//请求发生错误回调
	c.OnError(func(response *colly.Response, err error) {
		fmt.Printf("发生错误了:%v", err)
	})

	// 在所有OnHTML之后执行,可以用来做一些回收操作
	c.OnScraped(func(response *colly.Response) {
		fmt.Println("----> 所有匹配已完成")
	})

	// 和OnHTML类似,用于匹配xpath解析
    // 匹配:百度首页左上方链接
	c.OnXML("//div[@id='s-top-left']/a", func(element *colly.XMLElement) {
		text := element.Text
		href := element.Attr("href")
		fmt.Printf("名称:%s -> 连接:%s\n", text, href)
	})

	// 开始访问
	err := c.Visit("http://www.baidu.com/")
	if err != nil {
		log.Fatalln(err)
		return
	}
}
PS D:\dev\go\workspace\go-colly-demo> go run .\demo2.go
----> 开始请求了
----> 有结果返回了
匹配到目标元素ID su: 百度一下
匹配到目标元素ID kw, 最多允许输入: 255
名称:新闻 -c> 连接:http://news.baidu.com
名称:hao123 -c> 连接:https://www.hao123.com?src=from_pc
名称:地图 -c> 连接:http://map.baidu.com
名称:贴吧 -c> 连接:http://tieba.baidu.com/
名称:视频 -c> 连接:https://haokan.baidu.com/?sfrom=baidu-top
名称:图片 -c> 连接:http://image.baidu.com/
名称:网盘 -c> 连接:https://pan.baidu.com?from=1026962h
----> 所有匹配已完成

2.2 goquerySelector 语法

OnHTML方法的第一个参数是选择器,goquery选择器语法类似jquery,可以认为它是jquery的go版本实现。这里简单介绍常用的选择器,具体可以参考jquery选择器使用。

  • ID选择器: #id-name 根据元素id属性进行选择
  • 类选择器:.class-name 根据class名称选择
  • 标签选择器:div 根据标签名字选择
  • 子元素选择器:parent>child 筛选parent这个父元素下,符合child这个条件的最直接的子元素,不会匹配孙子元素
  • 子孙选择器:parent son 空格隔开代表可以匹配非直接子元素也就包括子孙元素了
  • prev+next相邻选择器:选择相邻的元素

2.3 xpath语法

OnXML 的第一个参数为xpath选择器,用的相对少一些,可以自行搜索语法学期,这里不再赘述,余下代码实例都用goquery选择器

XPath 语法 (w3school.com.cn)

2.4 *colly.HTMLElement常用方法

	c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
		// 
	})

2.4.1 常用属性

Name:获取元素名称

Text:获取元素文本内容,包括子元素的内容

DOM:返回goquery dom对象,可以调用goquery的方法进行操作:Find、Has、After 等

c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
    fmt.Println(e.Name)
    fmt.Println(e.Text)
})
PS D:\dev\go\workspace\go-colly-demo> go run .\demo3.go
div
新闻hao123地图贴吧视频图片网盘更多翻译学术文库百科知道健康营销推广直播音乐查看全部百度产品 >

2.4.2 常用的方法

Attr:Attr(k string) string 获取元素指定属性

cs := e.Attr("class")

ForEach:ForEach(goquerySelector string, callback func(int, *HTMLElement)) 在当前元素的遍历所有符合指定条件的元素

c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
    e.ForEach("a", func(i int, element *colly.HTMLElement) {
        fmt.Printf("第%d超链接\t %s :: %s\n", i, element.Text, element.Attr("href"))
    })
})
PS D:\dev\go\workspace\go-colly-demo> go run .\demo3.go
第0超链接        新闻 :: http://news.baidu.com
第1超链接        hao123 :: https://www.hao123.com?src=from_pc
第2超链接        地图 :: http://map.baidu.com
第3超链接        贴吧 :: http://tieba.baidu.com/
第4超链接        视频 :: https://haokan.baidu.com/?sfrom=baidu-top
第5超链接        图片 :: http://image.baidu.com/
第6超链接        网盘 :: https://pan.baidu.com?from=1026962h
第7超链接        更多 :: http://www.baidu.com/more/
第8超链接        翻译 :: http://fanyi.baidu.com/
第9超链接        学术 :: http://xueshu.baidu.com/
第10超链接       文库 :: https://wenku.baidu.com
第11超链接       百科 :: https://baike.baidu.com
第12超链接       知道 :: https://zhidao.baidu.com
第13超链接       健康 :: https://jiankang.baidu.com/widescreen/home
第14超链接       营销推广 :: http://e.baidu.com/ebaidu/home?refer=887
第15超链接       直播 :: https://live.baidu.com/
第16超链接       音乐 :: http://music.taihe.com
第17超链接       查看全部百度产品 > :: http://www.baidu.com/more/

ForEachWithBreak:和ForEach类似,但是可以根据指定返回true false控制是否终止循环

c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
    e.ForEachWithBreak("a", func(i int, element *colly.HTMLElement) bool {
        fmt.Printf("第%d超链接\t %s :: %s\n", i, element.Text, element.Attr("href"))
        return i < 3
    })
})
PS D:\dev\go\workspace\go-colly-demo> go run .\demo3.go
第0超链接        新闻 :: http://news.baidu.com
第1超链接        hao123 :: https://www.hao123.com?src=from_pc
第2超链接        地图 :: http://map.baidu.com
第3超链接        贴吧 :: http://tieba.baidu.com/

ChildAttrs:(goquerySelector, attrName string) []string 在当前元素下匹配指定元素,并返回指定的属性值

c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
    attrs := e.ChildAttrs("a", "href")
    for i, attr := range attrs {
        fmt.Printf("第%d个a标签的href属性: %s\n", i, attr)
    }
})
PS D:\dev\go\workspace\go-colly-demo> go run .\demo3.go
第0个a标签的href属性: http://news.baidu.com
第1个a标签的href属性: https://www.hao123.com?src=from_pc
第2个a标签的href属性: http://map.baidu.com
第3个a标签的href属性: http://tieba.baidu.com/
第4个a标签的href属性: https://haokan.baidu.com/?sfrom=baidu-top
第5个a标签的href属性: http://image.baidu.com/
第6个a标签的href属性: https://pan.baidu.com?from=1026962h
第7个a标签的href属性: http://www.baidu.com/more/
第8个a标签的href属性: http://fanyi.baidu.com/
第9个a标签的href属性: http://xueshu.baidu.com/
第10个a标签的href属性: https://wenku.baidu.com
第11个a标签的href属性: https://baike.baidu.com
第12个a标签的href属性: https://zhidao.baidu.com
第13个a标签的href属性: https://jiankang.baidu.com/widescreen/home
第14个a标签的href属性: http://e.baidu.com/ebaidu/home?refer=887
第15个a标签的href属性: https://live.baidu.com/
第16个a标签的href属性: http://music.taihe.com
第17个a标签的href属性: http://www.baidu.com/more/

ChildTexts:ChildTexts(goquerySelector string) []string 在当前元素下匹配指定元素,并返回指定元素的text内容

c.OnHTML("#s-top-left", func(e *colly.HTMLElement) {
    texts := e.ChildTexts("a")
    fmt.Println(strings.Join(texts, ", "))
})
PS D:\dev\go\workspace\go-colly-demo> go run .\demo3.go
新闻, hao123, 地图, 贴吧, 视频, 图片, 网盘, 更多, 翻译, 学术, 文库, 百科, 知道, 健康, 营销推广, 直播, 音乐, 查看全部百度产品 >

3 高级配置

3.1 收集器配置-UserAgent

用来设置浏览器UA头

c := colly.NewCollector(
    colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"),
)

c.OnRequest(func(request *colly.Request) {
    fmt.Println("User-Agent:", request.Headers.Get("User-Agent"))
})

3.2 收集器配置-Async

设置网络请求异步处理,异步之后需要调用c.Wait()

package main

import (
	"fmt"
	"github.com/gocolly/colly/v2"
	"time"
)

func main() {
	// Instantiate default collector
	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"),
		colly.Async(),
		colly.MaxDepth(2),
	)

	c.OnRequest(func(request *colly.Request) {
		fmt.Println("开始请求:", request.URL)
	})
	c.OnHTML("#s-top-left a", func(e *colly.HTMLElement) {
		link := e.Attr("href")
		e.Request.Visit(link)
	})

	now := time.Now()
	c.Visit("https://baidu.com/")
	// Wait until threads are finished
	c.Wait()
	fmt.Println("耗时:", time.Now().Sub(now).Milliseconds())
}

测试结果

关闭异步:5~6s

开启异步:1~2s

3.3 收集器配置-MaxDepth

限制访问的URL的递归深度

3.4 收集器配置-AllowedDomains

设置允许请求的域名主机,可以是多个,Visit只会发起这些域名下的请求

	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"),
		colly.Async(true),
		colly.AllowedDomains("www.baidu.com", "wiki.hackerspaces.org"),
	)

3.5 收集器配置-IgnoreRobotsTxt

设置忽略robots协议

robots协议也称爬虫协议、爬虫规则等,是指网站可建立一个robots.txt文件来告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取,而搜索引擎则通过读取robots.txt文件来识别这个页面是否允许被抓取。但是,这个robots协议不是防火墙,也没有强制执行力,搜索引擎完全可以忽视robots.txt文件去抓取网页的快照。

	c := colly.NewCollector(
		colly.IgnoreRobotsTxt(),
	)

3.6 收集器配置-CacheDir

设置GET请求本地缓存文件夹

	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"),
		colly.Async(true),
		colly.AllowedDomains("www.baidu.com", "wiki.hackerspaces.org"),
		colly.IgnoreRobotsTxt(),
		colly.CacheDir("cache-dir"),
	)

3.7 收集器配置-AllowURLRevisit

允许同一个收集器多次访问同一个地址

colly.AllowURLRevisit(),

3.8 并发请求设置

c.Limit(&colly.LimitRule{
    DomainGlob:  "*baidu.*", // 匹配URL包含baidu的
    Parallelism: 10, // 并发请求10
    RandomDelay: 5 * time.Second, // 设置发起请求随机延时0-5
})

例子:

package main

import (
	"fmt"
	"github.com/gocolly/colly/v2"
	"time"
)

func main() {
	// Instantiate default collector
	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"),
		colly.Async(),
		colly.MaxDepth(2),
		colly.AllowURLRevisit(),
	)

	c.Limit(&colly.LimitRule{
		DomainGlob:  "*baidu.*",
		Parallelism: 10,
		RandomDelay: 5 * time.Second,
	})

	//c.Limit(&colly.LimitRule{DomainGlob: "*", Parallelism: 2})
	c.OnRequest(func(request *colly.Request) {
		fmt.Println("开始请求:", request.URL)
	})
	c.OnResponse(func(response *colly.Response) {
		fmt.Println("请求结束:", response.Request.URL)
		fmt.Println("------------")
	})
	c.OnHTML("#s-top-left a", func(e *colly.HTMLElement) {
		link := e.Attr("href")
		e.Request.Visit(link)
	})

	now := time.Now()
	c.Visit("https://baidu.com/")
	// Wait until threads are finished
	c.Wait()
	fmt.Println("耗时:", time.Now().Sub(now).Milliseconds())
}

3.9 配置代理

频繁访问网站,会面临IP被封,需要进行代理池设置,colly支持http https socks5的代理

这里使用"快代理"免费代理池测试;国内高匿HTTP免费代理IP - 快代理 (kuaidaili.com) 免费的极其不稳定,测试过程中-_-碰运气

// 设置代理:http https socks5
proxyPool, err := proxy.RoundRobinProxySwitcher("http://111.3.102.207:30001", "http://183.247.211.41:30001")
if err != nil {
    fmt.Println("设置代理失败", err)
    return
}
c.SetProxyFunc(proxyPool)

3.10 上传multipart文件

colly的收集器,提供了 PostMultipart方法用来上传文件,这里贴出一个官方的小demo

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"time"

	"github.com/gocolly/colly/v2"
)

func generateFormData() map[string][]byte {
	f, _ := os.Open("gocolly.jpg")
	defer f.Close()

	imgData, _ := ioutil.ReadAll(f)

	return map[string][]byte{
		"firstname": []byte("one"),
		"lastname":  []byte("two"),
		"email":     []byte("onetwo@example.com"),
		"file":      imgData,
	}
}

func setupServer() {
	var handler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("received request")
		err := r.ParseMultipartForm(10000000)
		if err != nil {
			fmt.Println("server: Error")
			w.WriteHeader(500)
			w.Write([]byte("<html><body>Internal Server Error</body></html>"))
			return
		}
		w.WriteHeader(200)
		fmt.Println("server: OK")
		w.Write([]byte("<html><body>Success</body></html>"))
	}

	go http.ListenAndServe(":8080", handler)
}

func main() {
	// Start a single route http server to post an image to.
	setupServer()

	c := colly.NewCollector(colly.AllowURLRevisit(), colly.MaxDepth(5))

	// On every a element which has href attribute call callback
	c.OnHTML("html", func(e *colly.HTMLElement) {
		fmt.Println(e.Text)
		time.Sleep(1 * time.Second)
		e.Request.PostMultipart("http://localhost:8080/", generateFormData())
	})

	// Before making a request print "Visiting ..."
	c.OnRequest(func(r *colly.Request) {
		fmt.Println("Posting gocolly.jpg to", r.URL.String())
	})

	// Start scraping
	c.PostMultipart("http://localhost:8080/", generateFormData())
	c.Wait()
}

3.11 Cookies处理

请求中难免会遇到cookies处理的情况:

  • cookiejar go 语言net包提供的:net/http/cookiejar用来存储cookies

    colly 收集器提供了两个方法:SetCookieJar和SetCookies来设置请求

    cjar, err := cookiejar.New(nil)
    if err != nil {
        fmt.Println("创建cookiejar失败", err)
    }
    // 设置cookiejar
    c.SetCookieJar(cjar)
    // 请求发起时候打印cookies
    c.OnRequest(func(request *colly.Request) {
        cookies := cjar.Cookies(request.URL)
        fmt.Println(cookies)
        fmt.Println("开始请求:", request.URL, ", cookies:", cookies)
    })
    

4 综合实战

4.1 抓取笔趣阁小说

网站地址:http://www.bqg5200.net/16/16705/ 伏天氏小说章节抓取

代码实现:

package main

import (
	"bufio"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/gocolly/colly/v2"
	"github.com/gocolly/colly/v2/extensions"
	"log"
	"os"
	"strings"
	"time"
)

type PageChapter struct {
	Name  string `json:"name"`
	Url   string `json:"url"`
	Index int    `json:"index"`
}

func GetNewCollector() *colly.Collector {
	collector := colly.NewCollector(
		func(collector *colly.Collector) {
			// 设置随机ua
			extensions.RandomUserAgent(collector)
		},
		func(collector *colly.Collector) {
			collector.OnRequest(func(request *colly.Request) {
				log.Println(request.URL, ", User-Agent:", request.Headers.Get("User-Agent"))
			})
		},
	)
	collector.SetRequestTimeout(time.Second * 60)
	return collector
}

func BqgChapterParse(url string) ([]PageChapter, error) {
	var cha []PageChapter
	collector := GetNewCollector()
	collector.OnHTML(".listmain dl", func(element *colly.HTMLElement) {
		element.DOM.Children().Each(func(i int, selection *goquery.Selection) {
			selection = selection.ChildrenFiltered("a")
			link, _ := selection.Attr("href")
			name := strings.TrimSpace(selection.Text())
			cha = append(cha, PageChapter{
				Index: i,
				Url:   element.Request.AbsoluteURL(link),
				Name:  name,
			})
		})
	})
	err := collector.Visit(url)
	return cha, err
}

func writeTxt(fileName string, chapters []PageChapter) {
	f, err := os.Create(fileName)
	if err != nil {
		fmt.Println("创建文件失败,", err)
		return
	}
	defer f.Close()
	w := bufio.NewWriter(f)

	for _, chapter := range chapters {
		w.WriteString(fmt.Sprintf("%d %s %s\n", chapter.Index, chapter.Name, chapter.Url))
	}
	w.Flush()
}

func main() {
	log.Println("开始抓取")
	parse, err := BqgChapterParse("http://www.bqg5200.net/16/16705/")
	if err != nil {
		log.Fatalf("解析章节错误:%v", err)
	}
	log.Println("抓取结束")
	writeTxt("16705.txt", parse)
	log.Println("写入文件结束")
}
0  http://www.bqg5200.net/16/16705/
1 第一章 此间少年 http://www.bqg5200.net/16/16705/4845336.html
2 第二章 三年聚气 http://www.bqg5200.net/16/16705/4845337.html
3 第三章 一日三境 http://www.bqg5200.net/16/16705/4845338.html
4 第四章 太阳命魂 http://www.bqg5200.net/16/16705/4845339.html
5 第五章 风晴雪的决定 http://www.bqg5200.net/16/16705/4845340.html
6 第六章 有龙出没 http://www.bqg5200.net/16/16705/4845341.html
7 第七章 刻箓师 http://www.bqg5200.net/16/16705/4845342.html
8 第八章 万众瞩目 http://www.bqg5200.net/16/16705/4845343.html
9 第九章 文试 http://www.bqg5200.net/16/16705/4845344.html
10 第十章 一鸣惊人 http://www.bqg5200.net/16/16705/4845345.html
11 第十一章 妖精害我 http://www.bqg5200.net/16/16705/4845346.html
12 第十二章 师兄弟 http://www.bqg5200.net/16/16705/4845347.html
13 第十三章 一日功成 http://www.bqg5200.net/16/16705/4845348.html
14 第十四章 论战 http://www.bqg5200.net/16/16705/4845349.html
15 第十五章 太嚣张了 http://www.bqg5200.net/16/16705/4845350.html
16 第十六章 年少轻狂 http://www.bqg5200.net/16/16705/4845351.html
17 第十七章 我不服 http://www.bqg5200.net/16/16705/4845352.html
。。。
。。。

4.2 抓取百度热搜

地址:百度热搜 (baidu.com)

代码实现:

package main

import (
	"fmt"
	"github.com/gocolly/colly/v2"
	"github.com/gocolly/colly/v2/extensions"
	"log"
	"time"
)

type HotItem struct {
	Link  string
	Img   string
	Title string
	Desc  string
	Hot   int
}

func main() {
	collector := colly.NewCollector(
		func(collector *colly.Collector) {
			// 设置随机ua
			extensions.RandomUserAgent(collector)
		},
		func(collector *colly.Collector) {
			collector.OnRequest(func(request *colly.Request) {
				log.Println(request.URL, ", User-Agent:", request.Headers.Get("User-Agent"))
			})
		},
	)
	collector.SetRequestTimeout(time.Second * 60)

	data := []HotItem{}

	collector.OnHTML(".container-bg_lQ801", func(element *colly.HTMLElement) {
		element.ForEach(".category-wrap_iQLoo", func(i int, element *colly.HTMLElement) {
			aLink := element.DOM.ChildrenFiltered("a")
			jumpLink, _ := aLink.Attr("href")
			imgLink, _ := aLink.ChildrenFiltered("img").Attr("src")

			title := element.ChildText(".content_1YWBm .c-single-text-ellipsis")
			desc := element.ChildText(".content_1YWBm .large_nSuFU ")
			data = append(data, HotItem{
				Link:  jumpLink,
				Img:   imgLink,
				Title: title,
				Desc:  desc,
			})
		})
	})

	err := collector.Visit("https://top.baidu.com/board?tab=realtime")
	if err != nil {
		log.Fatalf("%v", err)
	}

	for i := range data {
		fmt.Printf("[%d]标题:%s, 链接:%s, 图片地址:%s, 描述:%s\n", i, data[i].Title, data[i].Link, data[i].Img, data[i].Desc)
	}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/22520.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pdf如何删除其中一页?不妨试试这些办法

PDF格式是一种非常常见的文档格式&#xff0c;它可以在各种系统和设备上使用&#xff0c;而且无论在哪里打开&#xff0c;都可以保持格式的一致性。有时候&#xff0c;我们需要删除PDF文档中的一页&#xff0c;无论是为了更改文档的结构&#xff0c;还是为了删除错误的信息。在…

拥抱生成式大模型 --- 提示工程篇

本文为系列的第二篇&#xff0c;主要是学习和总结chatgpt类模型的提示工程。感谢吴恩达老师的开源课程。 引言 随着大型语言模型&#xff08;LLM&#xff09;的发展&#xff0c;LLM 大致可以分为两种类型&#xff0c;即基础LLM和指令微调LLM。基础LLM是基于文本训练数据&…

Python机器学习入门 - - 贝叶斯算法学习笔记

文章目录 前言一、贝叶斯算法简介二、贝叶斯算法的数学原理1. 条件概率2. 全概率公式3. 贝叶斯公式4. 朴素贝叶斯分类器5. 高斯朴素贝叶斯分类器和伯努利朴素贝叶斯分类器 三、Python实现朴素贝叶斯分类总结 前言 贝叶斯公式是我们高中就耳熟能详的统计概率定理&#xff0c;贝…

亚马逊云科技出海日6月9日盛夏盛启

向全球价值链上游奋进 中国企业增强国际竞争力的关键&#xff0c;是努力朝全球价值链上游奋进&#xff0c;发力技术出海。中国的出海新机遇&#xff0c;背后曾是疫情在全球按下数字互联和数字化升级的快进键&#xff0c;跨境电商、在线社交、移动支付、数字服务等数字经济迎来…

如何让你的 Jmeter+Ant 测试报告更具吸引力?

目录 引言 一、安装apache-Ant 二、Jmeter准备 3、生成测试报告 4、JMeter动态参数处理逻辑是什么&#xff1f; 5、JMeter是怎么做API自动化测试的&#xff1f; 结语 引言 想象一下&#xff0c;你辛苦搭建了一个复杂的网站&#xff0c;投入了大量的时间和精力进行开发和…

005 - STM32学习笔记 - 启动代码

005 - STM32学习笔记 - 启动代码 常用汇编指令 指令名称作用EQU给数字常量取一个符号名&#xff0c;相当于C语言中的#define&#xff1b;AREA汇编一个新的代码段或者数据段&#xff1b;SPACE分配内存空间&#xff1b;PRESERVE8当前文件栈需要按照8字节对齐&#xff1b;EXPORT…

k8s pv pvc的介绍|动态存储|静态存储

k8s pv pvc的介绍|动态存储|静态存储 1 emptyDir存储卷2 hostPath存储卷3 nfs共享存储卷4 PVC 和 PVNFS使用PV和PVC 4 搭建 StorageClass NFS&#xff0c;实现 NFS 的动态 PV 创建 1 emptyDir存储卷 当Pod被分配给节点时&#xff0c;首先创建emptyDir卷&#xff0c;并且只要该…

详解c++STL—函数对象

目录 1、函数对象 1.1、函数对象概念 1.2、函数对象的使用 2、谓词 2.1、谓词概念 2.2、一元谓词 2.3、二元谓词 3、内建函数对象 3.1、理解内建函数对象 3.2、算术仿函数 3.3、关系仿函数 3.4、逻辑仿函数 1、函数对象 1.1、函数对象概念 概念&#xff1a; 重载…

编译原理个人作业--第六章——基于 编译原理 国防工业出版社 第三版

2 对表达式((a)(b)) (1) 按照表6.4属性文法构造抽象语法树 (2) 按6.17翻译模式构造表达式抽象语法树 5(1) 下列文法对整型常数、实型常熟世家加法运算符 生成表达式&#xff0c;当两个整型数相加&#xff0c;结果为整形&#xff0c;否则结果为实型 E → E T ∣ T E\r…

面试技术点

一、对热修复、插件化、模块化、组件化有一定研究。 1、模块化 将共享部分或业务模块抽取出来形成独立module。 2、组件化 基于模块化&#xff0c;核心思想是角色的转换&#xff0c;在打包时是library&#xff0c;分离独立的业务组件如微信朋友圈。 3、热修复和插件化种类、…

电力系统机组组合优化调度(IEEE14节点、IEEE30节点、IEEE118节点)(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

Java并发编程-synchronized

目录 1. synchronized在jdk 1.6中的优化 1.1 锁消除 1.2 锁粗化 1.2 锁升级/锁膨胀 1.2.1 锁升级原理 1.2.2 自适应自旋锁 2. synchronized实现原理 3. synchronized和Lock的对比 1. synchronized在jdk 1.6中的优化 在JDK1.5的时候,Doug Lee推出了ReentrantLock,lock的…

chatgpt赋能Python-python_os拷贝文件

Python os拷贝文件 – 从简介到实现 Python os库是一个经常使用的工具&#xff0c;它是Python的标准库&#xff0c;提供了与操作系统进行交互的函数和方法。其中&#xff0c;os拷贝文件是其常用的功能之一&#xff0c;可以用来实现文件备份、文件复制等等操作。接下来&#xf…

windows sever服务器安装系统新手版

混在learnsite群里已经有几年了吧&#xff0c;但是只有一段时间用了别人现成的一个iso版本还比较老&#xff0c;这次打算自己弄一个&#xff0c;一开始打算linux下弄&#xff0c;结果系统都装完了发现人家说learnsite在linux下有点bug没解决好&#xff0c;只能win下再弄&#x…

Vue+uniapp桃源婚恋交友APP 安卓小程序 nodejs java python

小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 开发模式&#xff1a;混合开发本文先提出了开发基于小程序的桃源婚恋交友APP系统的背景意义&#xff0c;然后通过功能性和非功能性分析阐述本系统的需求&#xff0c;然后进行系统设计。技术实现部分选择Jav…

据不可靠消息,ST的新一代机皇正式命名为STM32V8系列,搭载Cortex-M85内核

根据以往的传统单片机命名方式&#xff1a; C0, L0, G0, F0 > Cortex-M0内核 F1, L1 > Corterx-M3内核 F2, F3 > Corterx-M3/M4 F4&#xff0c;G4&#xff0c;L4, L4 > Cortex-M4内核 L5&#xff0c;U5, H5 > Cor…

web安全第一天 ,域名,dns

第一天 什么是域名&#xff1f;域名就是网络地址 在hhtp之后的就是域名 域名在哪里注册呢 国内注册商有很多&#xff0c;在网络上搜索一下阿里云万网就可以注册 什么是二级域名和多级域名 域名通常都是www.开头 &#xff0c;而www.被称为顶级域名&#xff0c;在搜索的时候…

部门来了个测试开发,听说是00后,上来一顿操作给我看呆了...

公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&#xff01…

深度学习量化总结(PTQ、QAT)

背景 目前神经网络在许多前沿领域的应用取得了较大进展&#xff0c;但经常会带来很高的计算成本&#xff0c;对内存带宽和算力要求高。另外降低神经网络的功率和时延在现代网络集成到边缘设备时也极其关键&#xff0c;在这些场景中模型推理具有严格的功率和计算要求。神经网络…

5月份招了个00后测试堪称卷王之王,让人崩溃...

前段时间公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司干了三年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&am…