前端頁面展示


爬蟲前端頁面展示

前端頁面展示架構

鏈接Elasticsearch

1.在docker里運行elasticsearch docker run -id -p 9200:9200 elasticsearch
2.下載elastic庫。https://github.com/olivere/elastic,選擇相應的版本(本項目5.0版本),獲取軟件包go get gopkg.in/olivere/elastic.v5

3.如果您的Elasticsearch服務器在不同的IP和/或端口上運行,只需提供一個指向NewClient的URL:

// Create a client and connect to http://192.168.2.10:9201
client, err := elastic.NewClient(elastic.SetURL("http://192.168.2.10:9201"))
if err != nil {
  // Handle error
}

但我們的elasticsearch運行在docker容器里,所以我們要從新指定地址:

// sniff 會請求http://ip:port/_nodes/http,將其返回的url list作為新的url list。
// 如果snifferEnabled被設置為false,那么則不啟動該功能。
client, err := elastic.NewClient(
		elastic.SetSniff(false),
		elastic.SetURL("http://192.168.200.17:9200"))
	if err != nil {
		return nil, err
	}

將數據存儲到Elasticsearch

func save(client *elastic.Client, index string, item engine.Item) error {
	if item.Type == "" {
		return errors.New("must supply Type")
	}
	indexService := client.Index(). //鏈接數據庫
		Index(index). //相當於MySQL里的數據庫
		Type(item.Type).//相當於MySQL里的表
		BodyJson(item) //把數據轉為json格式
	if item.Id != "" {
		indexService.Id(item.Id)
	}
	_, err := indexService.Do(context.Background()) 
	if err != nil {
		return err
	}
	return nil
}
這里我們定義了一個函數來調用。傳進來三個參數,client index item。
client: 是我們在外面創建好的鏈接elastic的客戶端。
index: 是外面用戶要鏈接elastic哪個索引(相當於MySQL的數據庫)
item: 存儲的數據
注意:
type Item struct { //參數item的類型
	Id string 
	Type string 
	Url string
	Payload interface{}
}

標准模板庫template(前端頁面)

基本語法

1.變量
模板內內嵌的語法支持,全部需要加{{}}來標記。
在模板文件內, . 代表了當前變量,即在非循環體內,.就代表了傳入的那個變量。假設我們定義了一個結構體:

type Article struct {
    ArticleId int
    ArticleContent string
}

那么我們在模板內可以通過

<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>

來獲取並把變量的內容渲染到模板內。假設上述的結構體的內容為ArticleId:1 ArticleContent:”hello”, 則對應渲染后的模板內容為:

<p>hello<span>1</span></p>

當然,我們有時候需要定義變量,比如我們需要定義一個article變量,同時將其初始化為”hello”,那么我們可以這樣寫:

{{$article := "hello"}}

假設我們想要把傳入值的內容賦值給article,則可以這樣寫:

{{$article := .ArticleContent}}

2.判斷
golang的模板也支持if的條件判斷,當前支持最簡單的bool類型和字符串類型的判斷

{{if .condition}}
{{end}}

當.condition為bool類型的時候,則為true表示執行,當.condition為string類型的時候,則非空表示執行。
當然也支持else , else if嵌套

{{if .condition1}}
{{else if .contition2}}
{{end}}

假設我們需要邏輯判斷,比如與或、大小不等於等判斷的時候,我們需要一些內置的模板函數來做這些工作,目前常用的一些內置模板函數有:

not 非

{{if not .condition}}
{{end}}

and 與

{{if and .condition1 .condition2}}
{{end}}

or 或

{{if or .condition1 .condition2}}
{{end}}

eq 等於

{{if eq .var1 .var2}}
{{end}}

ne 不等於

{{if ne .var1 .var2}}
{{end}}

lt 小於 (less than)

{{if lt .var1 .var2}}
{{end}}

le 小於等於

{{if le .var1 .var2}}
{{end}}

gt 大於

{{if gt .var1 .var2}}
{{end}}

ge 大於等於

{{if ge .var1 .var2}}
{{end}}

3.循環
golang的template支持range循環來遍歷map、slice內的內容,語法為:

{{range $i, $v := .slice}}
{{end}}

在這個range循環內,我們可以通過iv來訪問遍歷的值,還有一種遍歷方式為:

{{range .slice}}
{{end}}

這種方式無法訪問到index或者key的值,需要通過.來訪問對應的value

{{range .slice}}
{{.field}}
{{end}}

當然這里使用了.來訪問遍歷的值,那么我們想要在其中訪問外部的變量怎么辦?(比如渲染模板傳入的變量),在這里,我們需要使用$.來訪問外部的變量

{{range .slice}}
{{$.ArticleContent}}
{{end}}

實現前端展示

elastic查詢語法

//取所有
res, err = client.Search("megacorp").Type("employee").Do(context.Background())
printEmployee(res, err)

//字段相等
q := elastic.NewQueryStringQuery("last_name:Smith")
res, err = client.Search("megacorp").Type("employee").Query(q).Do(context.Background())
if err != nil {
println(err.Error())
}
//條件查詢
//年齡大於30歲的
boolQ := elastic.NewBoolQuery()
boolQ.Must(elastic.NewMatchQuery("last_name", "smith"))
boolQ.Filter(elastic.NewRangeQuery("age").Gt(30))
res, err = client.Search("megacorp").Type("employee").Query(q).Do(context.Background())
printEmployee(res, err)

//短語搜索 搜索about字段中有 rock climbing
matchPhraseQuery := elastic.NewMatchPhraseQuery("about", "rock climbing")
res, err = client.Search("megacorp").Type("employee").Query(matchPhraseQuery).Do(context.Background())
printEmployee(res, err)

在本項目中我的搜索沒有弄的那么強大:

func (h SearchResultHandler)  getSearchResult(q string, from int) (model.SearchResult, error) {
	var result model.SearchResult
	resp, err := h.client.Search("zhenai_date").
		Query(elastic.NewQueryStringQuery(rewriteQueryString(q))). //根據關鍵值去每個字段進行模糊查詢
		From(from).
		Do(context.Background())
	if err != nil {
		return result, err
	}
	result.Query = q
	result.Hits = resp.TotalHits()
	result.Start = from
	result.Items = resp.Each(reflect.TypeOf(engine.Item{}))
	result.PrevFrom = result.Start - len(result.Items) //分頁
	result.NextFrom = result.Start + len(result.Items)
	return result, nil
}
//把關鍵值重寫
func rewriteQueryString(q string) string  {
	re := regexp.MustCompile(`([A-z][a-z]*):`)
	return re.ReplaceAllString(q, "Payload.$1:")
}

前端頁面展示

前端頁面可以實現簡單的查詢和分頁。

總結

到此爬蟲的並發版和前端的展示完成。完整代碼:
https://github.com/cwyfengyiyuan/golang-crawler.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM