亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang goquery selector選擇器使用示例大全

 更新時(shí)間:2022年09月21日 14:39:10   作者:如此風(fēng)景  
這篇文章主要為大家介紹了golang goquery selector選擇器使用示例大全,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

最近研究Go爬蟲相關(guān)的知識(shí),使用到goquery這個(gè)庫(kù)比較多,尤其是對(duì)爬取到的HTML進(jìn)行選擇和查找匹配的內(nèi)容時(shí),goquery的選擇器使用尤其多,而且還有很多不常用但又很有用的選擇器,這里總結(jié)下,以供參考。

如果大家以前做過前端開發(fā),對(duì)jquery不會(huì)陌生,goquery類似jquery,它是jquery的go版本實(shí)現(xiàn)。使用它,可以很方便的對(duì)HTML進(jìn)行處理。

基于HTML Element 元素的選擇器

這個(gè)比較簡(jiǎn)單,就是基于a,p等這些HTML的基本元素進(jìn)行選擇,這種直接使用Element名稱作為選擇器即可。

比如dom.Find("div")

func main() {
	html := `<body>
				<div>DIV1</div>
				<div>DIV2</div>
				<span>SPAN</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

以上示例,可以把div元素篩選出來,而body,span并不會(huì)被篩選。

ID 選擇器

這個(gè)是使用頻次最多的,類似于上面的例子,有兩個(gè)div元素,其實(shí)我們只需要其中的一個(gè),那么我們只需要給這個(gè)標(biāo)記一個(gè)唯一的id即可,這樣我們就可以使用id選擇器,精確定位了。

func main() {
	html := `<body>
				<div id="div1">DIV1</div>
				<div>DIV2</div>
				<span>SPAN</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("#div1").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

Element ID 選擇器

id選擇器以#開頭,緊跟著元素id的值,使用語(yǔ)法為dom.Find(#id),后面的例子我會(huì)簡(jiǎn)寫為Find(#id),大家知道這是代表goquery選擇器的即可。

如果有相同的ID,但是它們又分別屬于不同的HTML元素怎么辦?有好辦法,和Element結(jié)合起來。比如我們篩選元素為div,并且iddiv1的元素,就可以使用Find(div#div1)這樣的篩選器進(jìn)行篩選。

所以這類篩選器的語(yǔ)法為Find(element#id),這是常用的組合方法,比如后面講的過濾器也可以采用這種方式組合使用。

Class選擇器

class也是HTML中常用的屬性,我們可以通過class選擇器來快速的篩選需要的HTML元素,它的用法和ID選擇器類似,為Find(".class")。

func main() {
	html := `<body>
				<div id="div1">DIV1</div>
				<div class="name">DIV2</div>
				<span>SPAN</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find(".name").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

以上示例中,就篩選出來classname的這個(gè)div元素。

Element Class 選擇器

class選擇器和id選擇器一樣,也可以結(jié)合著HTML元素使用,他們的語(yǔ)法也類似Find(element.class),這樣就可以篩選特定element、并且指定class的元素。

屬性選擇器

一個(gè)HTML元素都有自己的屬性以及屬性值,所以我們也可以通過屬性和值篩選元素。

func main() {
	html := `<body>
				<div>DIV1</div>
				<div class="name">DIV2</div>
				<span>SPAN</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div[class]").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

示例中我們通過div[class]這個(gè)選擇器,篩選出Element為div并且有class這個(gè)屬性的,所以第一個(gè)div沒有被篩選到。

剛剛上面這個(gè)示例是采用是否存在某個(gè)屬性為篩選器,同理,我們可以篩選出屬性為某個(gè)值的元素。

    dom.Find("div[class=name]").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})

這樣我們就可以篩選出class這個(gè)屬性值為namediv元素。

當(dāng)然我們這里以class屬性為例,還可以用其他屬性,比如href等很多,自定義屬性也是可以的。

除了完全相等,還有其他匹配方式,使用方式類似,這里統(tǒng)一列舉下,不再舉例

選擇器說明
Find(“div[lang]”)篩選含有l(wèi)ang屬性的div元素
Find(“div[lang=zh]”)篩選lang屬性為zh的div元素
Find(“div[lang!=zh]”)篩選lang屬性不等于zh的div元素
Find(“div[lang¦=zh]”)篩選lang屬性為zh或者zh-開頭的div元素
Find(“div[lang*=zh]”)篩選lang屬性包含zh這個(gè)字符串的div元素
Find(“div[lang~=zh]”)篩選lang屬性包含zh這個(gè)單詞的div元素,單詞以空格分開的
Find(“div[lang$=zh]”)篩選lang屬性以zh結(jié)尾的div元素,區(qū)分大小寫
Find(“div[lang^=zh]”)篩選lang屬性以zh開頭的div元素,區(qū)分大小寫

以上是屬性篩選器的用法,都是以一個(gè)屬性篩選器為例,當(dāng)然你也可以使用多個(gè)屬性篩選器組合使用,比如: Find("div[id][lang=zh]"),用多個(gè)中括號(hào)連起來即可。當(dāng)有多個(gè)屬性篩選器的時(shí)候,要同時(shí)滿足這些篩選器的元素才能被篩選出來。

parent>child選擇器

如果我們想篩選出某個(gè)元素下符合條件的子元素,我們就可以使用子元素篩選器,它的語(yǔ)法為Find("parent>child"),表示篩選parent這個(gè)父元素下,符合child這個(gè)條件的最直接(一級(jí))的子元素。

func main() {
	html := `<body>
				<div lang="ZH">DIV1</div>
				<div lang="zh-cn">DIV2</div>
				<div lang="en">DIV3</div>
				<span>
					<div>DIV4</div>
				</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("body>div").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

以上示例,篩選出body這個(gè)父元素下,符合條件的最直接的子元素div,結(jié)果是DIV1、DIV2、DIV3,雖然DIV4也是body的子元素,但不是一級(jí)的,所以不會(huì)被篩選到。

那么問題來了,我就是想把DIV4也篩選出來怎么辦?就是要篩選body下所有的div元素,不管是一級(jí)、二級(jí)還是N級(jí)。有辦法的,goquery考慮到了,只需要把大于號(hào)(>)改為空格就好了。比如上面的例子,改為如下選擇器即可。

    dom.Find("body div").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})

prev+next相鄰選擇器

假設(shè)我們要篩選的元素沒有規(guī)律,但是該元素的上一個(gè)元素有規(guī)律,我們就可以使用這種下一個(gè)相鄰選擇器來進(jìn)行選擇。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<p>P1</p>
				<div lang="zh-cn">DIV2</div>
				<div lang="en">DIV3</div>
				<span>
					<div>DIV4</div>
				</span>
				<p>P2</p>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div[lang=zh]+p").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})
}

這個(gè)示例演示了這種用法,我們想選擇<p>P1</p>這個(gè)元素,但是沒啥規(guī)律,我們發(fā)現(xiàn)它前面的<div lang="zh">DIV1</div>很有規(guī)律,可以選擇,所以我們就可以采用Find("div[lang=zh]+p")達(dá)到選擇P元素的目的。

這種選擇器的語(yǔ)法是("prev+next"),中間是一個(gè)加號(hào)(+),+號(hào)前后也是選擇器。

prev~next選擇器

有相鄰就有兄弟,兄弟選擇器就不一定要求相鄰了,只要他們共有一個(gè)父元素就可以。

	dom.Find("div[lang=zh]~p").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})

剛剛的例子,只需要把+號(hào)換成~號(hào),就可以把P2也篩選出來,因?yàn)?code>P2、P1DIV1都是兄弟。

兄弟選擇器的語(yǔ)法是("prev~next"),也就是相鄰選擇器的+換成了~。

內(nèi)容過濾器

有時(shí)候我們使用選擇器選擇出來后后,希望再過濾一下,這時(shí)候就用到過濾器了,過濾器有很多,我們先講內(nèi)容過濾器這一種。

	dom.Find("div:contains(DIV2)").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})

Find(":contains(text)")表示篩選出的元素要包含指定的文本,我們例子中要求選擇出的div元素要包含DIV2文本,那么只有一個(gè)DIV2元素滿足要求。

此外還有Find(":empty")表示篩選出的元素都不能有子元素(包括文本元素),只篩選那些不包含任何子元素的元素。

Find(":has(selector)")contains差不多,只不過這個(gè)是包含的是元素節(jié)點(diǎn)。

    dom.Find("span:has(div)").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Text())
	})

以上示例表示篩選出包含div元素的span節(jié)點(diǎn)。

:first-child過濾器

:first-child過濾器,語(yǔ)法為Find(":first-child"),表示篩選出的元素要是他們的父元素的第一個(gè)子元素,如果不是,則不會(huì)被篩選出來。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<p>P1</p>
				<div lang="zh-cn">DIV2</div>
				<div lang="en">DIV3</div>
				<span>
					<div style="display:none;">DIV4</div>
					<div>DIV5</div>
				</span>
				<p>P2</p>
				<div></div>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div:first-child").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Html())
	})
}

以上例子中,我們使用Find("div")會(huì)篩選出所有的div元素,但是我們加了:first-child后,就只有DIV1DIV4了,因?yàn)橹挥羞@兩個(gè)是他們父元素的第一個(gè)子元素,其他的DIV都不滿足。

:first-of-type過濾器

:first-child選擇器限制的比較死,必須得是第一個(gè)子元素,如果該元素前有其他在前面,就不能用:first-child了,這時(shí)候:first-of-type就派上用場(chǎng)了,它要求只要是這個(gè)類型的第一個(gè)就可以,我們把上面的例子微調(diào)下。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<p>P1</p>
				<div lang="zh-cn">DIV2</div>
				<div lang="en">DIV3</div>
				<span>
					<p>P2</p>
					<div>DIV5</div>
				</span>
				<div></div>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div:first-of-type").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Html())
	})
}

改動(dòng)很簡(jiǎn)單,把原來的DIV4換成了P2,如果我們還使用:first-child,DIV5是不能被篩選出來的,因?yàn)樗皇堑谝粋€(gè)子元素,它前面還有一個(gè)P2。這時(shí)候我們使用:first-of-type就可以達(dá)到目的,因?yàn)樗笫峭愋偷谝粋€(gè)就可以。DIV5就是這個(gè)div類型的第一個(gè)元素,P2不是div類型,被忽略。

:last-child 和 :last-of-type過濾器

這兩個(gè)正好和上面的:first-child、:first-of-type相反,表示最后一個(gè),這里不再舉例,大家可以自己試試。

:nth-child(n) 過濾器

這個(gè)表示篩選出的元素是其父元素的第n個(gè)元素,n以1開始。所以我們可以知道:first-child:nth-child(1)是相等的。通過指定n,我們就很靈活的篩選出我們需要的元素。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<p>P1</p>
				<div lang="zh-cn">DIV2</div>
				<div lang="en">DIV3</div>
				<span>
					<p>P2</p>
					<div>DIV5</div>
				</span>
				<div></div>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div:nth-child(3)").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Html())
	})
}

這個(gè)示例會(huì)篩選出DIV2,因?yàn)?code>DIV2是其父元素body的第三個(gè)子元素。

:nth-of-type(n) 過濾器

:nth-of-type(n)和 :nth-child(n) 類似,只不過它表示的是同類型元素的第n個(gè),所以:nth-of-type(1) 和 :first-of-type是相等的,大家可以自己試試,這里不再舉例。

nth-last-child(n) 和:nth-last-of-type(n) 過濾器

這兩個(gè)和上面的類似,只不過是倒序開始計(jì)算的,最后一個(gè)元素被當(dāng)成了第一個(gè)。大家自己測(cè)試下看看效果,很明顯。

:only-child 過濾器

Find(":only-child") 過濾器,從字面上看,可以猜測(cè)出來,它表示篩選的元素,在其父元素中,只有它自己,它的父元素沒有其他子元素,才會(huì)被匹配篩選出來。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<span>
					<div>DIV5</div>
				</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div:only-child").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Html())
	})
}

示例中DIV5就可以被篩選出來,因?yàn)樗撬母冈?code>span達(dá)到唯一子元素,但DIV1就不是,所以不能唄篩選出來。

:only-of-type 過濾器

上面的例子,如果想篩選出DIV1怎么辦?可以使用Find(":only-of-type"),因?yàn)樗撬母冈刂?,唯一?code>div元素,這就是:only-of-type過濾器所要做的,同類型元素只要只有一個(gè),就可以被篩選出來。大家把上面的例子改成:only-of-type試試,看看是否有DIV1。

選擇器或(|)運(yùn)算

如果我們想同時(shí)篩選出div,span等元素怎么辦?這時(shí)候可以采用多個(gè)選擇器進(jìn)行組合使用,并且以逗號(hào)(,)分割,Find("selector1, selector2, selectorN")表示,只要滿足其中一個(gè)選擇器就可以被篩選出來,也就是選擇器的或(|)運(yùn)算操作。

func main() {
	html := `<body>
				<div lang="zh">DIV1</div>
				<span>
					<div>DIV5</div>
				</span>
			</body>
			`
	dom,err:=goquery.NewDocumentFromReader(strings.NewReader(html))
	if err!=nil{
		log.Fatalln(err)
	}
	dom.Find("div,span").Each(func(i int, selection *goquery.Selection) {
		fmt.Println(selection.Html())
	})
}

小結(jié)

goquery 是解析HTML網(wǎng)頁(yè)必備的利器,在爬蟲抓取網(wǎng)頁(yè)的過程中,靈活的使用goquery不同的選擇器,可以讓我們的抓取工作事半功倍,大大提升爬蟲的效率。

以上就是golang goquery selector選擇器使用示例大全的詳細(xì)內(nèi)容,更多關(guān)于golang goquery selector選擇器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語(yǔ)言操作redis數(shù)據(jù)庫(kù)的方法

    Go語(yǔ)言操作redis數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Go語(yǔ)言操作redis數(shù)據(jù)庫(kù)的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 一步步教你在Linux上安裝Go語(yǔ)言環(huán)境

    一步步教你在Linux上安裝Go語(yǔ)言環(huán)境

    本文將介紹如何在Linux操作系統(tǒng)下搭建Go語(yǔ)言環(huán)境,Go語(yǔ)言是一種開源的編程語(yǔ)言,具有高效、簡(jiǎn)潔和并發(fā)性強(qiáng)的特點(diǎn),適用于開發(fā)各種類型的應(yīng)用程序,搭建Go語(yǔ)言環(huán)境是開始學(xué)習(xí)和開發(fā)Go語(yǔ)言項(xiàng)目的第一步,本文將詳細(xì)介紹安裝Go語(yǔ)言、配置環(huán)境變量以及驗(yàn)證安裝是否成功的步驟
    2023-10-10
  • Golang中 Slice的分析與使用源碼解析

    Golang中 Slice的分析與使用源碼解析

    這篇文章主要介紹了Golang 中 Slice的分析與使用(含源碼),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • 使用Go語(yǔ)言開發(fā)自動(dòng)化API測(cè)試工具詳解

    使用Go語(yǔ)言開發(fā)自動(dòng)化API測(cè)試工具詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Go語(yǔ)言開發(fā)自動(dòng)化API測(cè)試工具,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下
    2024-03-03
  • go程序執(zhí)行交叉編譯的流程步驟

    go程序執(zhí)行交叉編譯的流程步驟

    go程序可用通過交叉編譯的方式在一個(gè)平臺(tái)輸出多個(gè)平臺(tái)可運(yùn)行的二進(jìn)制包,本文給大家詳細(xì)介紹了go程序執(zhí)行交叉編譯的流程步驟,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2024-07-07
  • GO語(yǔ)言常用的文件讀取方式

    GO語(yǔ)言常用的文件讀取方式

    這篇文章主要介紹了GO語(yǔ)言常用的文件讀取方式,涉及一次性讀取、分塊讀取與逐行讀取等方法,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-12-12
  • Go語(yǔ)言常用字符串處理方法實(shí)例匯總

    Go語(yǔ)言常用字符串處理方法實(shí)例匯總

    這篇文章主要介紹了Go語(yǔ)言常用字符串處理方法,實(shí)例匯總了Go語(yǔ)言中常見的各種字符串處理技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • Golang filepath包常用函數(shù)詳解

    Golang filepath包常用函數(shù)詳解

    本文介紹與文件路徑相關(guān)包,該工具包位于path/filepath中,該包試圖與目標(biāo)操作系統(tǒng)定義的文件路徑兼容。本文介紹一些常用函數(shù),如獲取文件絕對(duì)路徑,獲取文件名或目錄名、遍歷文件、分割文件路徑、文件名模式匹配等函數(shù),并給具體示例進(jìn)行說明
    2023-02-02
  • windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    windows下使用vscode搭建golang環(huán)境并調(diào)試的過程

    這篇文章主要介紹了在windows下使用vscode搭建golang環(huán)境并進(jìn)行調(diào)試,主要包括安裝方法及環(huán)境變量配置技巧,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Go中strings包的基本使用示例代碼

    Go中strings包的基本使用示例代碼

    本文詳細(xì)介紹了Go語(yǔ)言中strings包的基本使用方法,包括字符串的前綴、后綴判斷,字符串包含、索引查找、字符串替換、計(jì)數(shù)、重復(fù)、大小寫轉(zhuǎn)換、修剪、分割、拼接以及數(shù)據(jù)類型轉(zhuǎn)換等功能,示例代碼豐富,適合初學(xué)者和需要使用字符串處理功能的開發(fā)者參考學(xué)習(xí)
    2024-10-10

最新評(píng)論