golang爬取珍爱网,爬到了3万多用户信息,并存到了elasticsearch中,如下图,查询到了3万多用户信息。

image.png

先来看看最终效果:

42.gif

利用到了go语言的html模板库:

执行模板渲染:func (s SearchResultView) Render (w io.Writer, data model.SearchResult) error {    return s.template.Execute(w, data)

}

model.SearchResult数据结构如下:type SearchResult struct {

Hits int64

Start int

Query string

PrevFrom int

NextFrom int

CurrentPage int

TotalPage int64

Items []interface{}    //Items []engine.Item}```htmlhtml>

Love Search

id="bootstrap-css">

搜索

共为你找到相关结果为{{.Hits}}个。显示从{{.Start}}起共{{len .Items}}个

昵称性别年龄身高体重收入学历职位所在地星座购房情况购车情况

{{range .Items}}

{{.Payload.Name}}

{{with .Payload}}

{{.Gender}}{{.Age}}{{.Height}}CM{{.Weight}}KG{{.Income}}{{.Education}}{{.Occupation}}{{.Hukou}}{{.Xinzuo}}{{.House}}{{.Car}}

{{end}}

{{else}}

没有找到相关用户

{{end}}

{{if gt .CurrentPage 1}}            上一页

{{end}}

{{if lt .CurrentPage .TotalPage}}            下一页

{{end}}            共{{.TotalPage}}页,当前第{{.CurrentPage}}页

其中用到了模板语法中的变量、函数、判断、循环;

模板函数的定义:

上面模板代码中的上一页、下一页的a标签href里用到了自定义模板函数Add和Sub分别用于获取上一页和下一页的页码,传到后台(这里并没有用JavaScript去实现)。

html/template包中提供的功能有限,所以很多时候需要使用用户定义的函数来辅助渲染页面。下面讲讲模板函数如何使用。template包创建新的模板的时候,支持.Funcs方法来将自定义的函数集合导入到该模板中,后续通过该模板渲染的文件均支持直接调用这些函数。

函数声明// Funcs adds the elements of the argument map to the template's function map.// It panics if a value in the map is not a function with appropriate return// type. However, it is legal to overwrite elements of the map. The return// value is the template, so calls can be chained.func (t *Template) Funcs(funcMap FuncMap) *Template {

t.text.Funcs(template.FuncMap(funcMap))    return t

}

Funcs方法就是用来创建我们模板函数了,它需要一个FuncMap类型的参数:// FuncMap is the type of the map defining the mapping from names to// functions. Each function must have either a single return value, or two// return values of which the second has type error. In that case, if the// second (error) argument evaluates to non-nil during execution, execution// terminates and Execute returns that error. FuncMap has the same base type// as FuncMap in "text/template", copied here so clients need not import// "text/template".type FuncMap map[string]interface{}

使用方法:

在go代码中定义两个函数Add和Sub://减法,为了在模板里用减1func Sub(a, b int) int {    return a - b

}//加法,为了在模板里用加1func Add(a, b int) int {    return a + b

}

模板绑定模板函数:

创建一个FuncMap类型的map,key是模板函数的名字,value是刚才定义函数名。

将 FuncMap注入到模板中。filename := "../view/template_test.html"template, err := template.New(path.Base(filename)).Funcs(template.FuncMap{"Add": Add, "Sub": Sub}).ParseFiles(filename)if err != nil {

t.Fatal(err)

}

模板中如何使用:

如上面html模板中上一页处的:{{Sub .CurrentPage 1}}

把渲染后的CurrentPage值加1

注意:

1、函数的注入,必须要在parseFiles之前,因为解析模板的时候,需要先把函数编译注入。

2、Template object can have multiple templates in it and each one has a name. If you look at the implementation of ParseFiles, you see that it uses the filename as the template name inside of the template object. So, name your file the same as the template object, (probably not generally practical) or else use ExecuteTemplate instead of just Execute.

3、The name of the template is the bare filename of the template, not the complete path。如果模板名字写错了,执行的时候会出现:error: template: “…” is an incomplete or empty template

尤其是第三点,我今天就遇到了,模板名要用文件名,不能是带路径的名字,看以下代码:func TestTemplate3(t *testing.T) {    //filename := "crawler/frontend/view/template.html"

filename := "../view/template_test.html"

//file, _ := os.Open(filename)

t.Logf("baseName:%s\n", path.Base(filename))

tpl, err := template.New(filename).Funcs(template.FuncMap{"Add": Add, "Sub": Sub}).ParseFiles(filename)    if err != nil {

t.Fatal(err)

}

page := common.SearchResult{}

page.Hits = 123

page.Start = 0

item := engine.Item {

Url:  "http://album.zhenai.com/u/107194488",

Type: "zhenai",

Id:   "107194488",

Payload: model.Profile{

Name:       "霓裳",

Age:        28,

Height:     157,

Marriage:   "未婚",

Income:     "5001-8000元",

Education:  "中专",

Occupation: "程序媛",

Gender:     "女",

House:      "已购房",

Car:        "已购车",

Hukou:      "上海徐汇区",

Xinzuo:    "水瓶座",

},

}

page.CurrentPage = 1

page.TotalPage = 10

page.Items = append(page.Items, item)

afterHtml, err := os.Create("template_test1.html")    if err != nil {

t.Fatal(err)

}

tpl.Execute(afterHtml, page)

}

这里在template.New(filename)传入的是文件名(上面定义时是带路径的文件名),导致执行完代码后template_test1.html文件是空的,当然测试类的通过的,但是将此渲染到浏览器的时候,就会报:template: “…” is an incomplete or empty template

所以,要使用文件的baseName,即:tpl, err := template.New(path.Base(filename)).Funcs(template.FuncMap{"Add": Add, "Sub": Sub}).ParseFiles(filename)

这样运行代码后template_test1.html就是被渲染有内容的。

其他语法:变量、判断、循环用法比较简单,我没遇到问题;其他语法,如:模板的嵌套,我目前没用到,在此也不做赘述。

查询遇到的问题:

因为查询每页显示10条记录,查询第1000页是正常的,当查询大于等于1001页的时候,会报如下错误:

image.png

用restclient工具调,错误更明显了:{  "error" : {    "root_cause" : [

{        "type" : "query_phase_execution_exception",        "reason" : "Result window is too large, from + size must be less than or equal to: [10000] but was [10010]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."

}

],    "type" : "search_phase_execution_exception",    "reason" : "all shards failed",    "phase" : "query",    "grouped" : true,    "failed_shards" : [

{        "shard" : 0,        "index" : "dating_profile",        "node" : "bJhldvT6QeaRTvHmBKHT4Q",        "reason" : {          "type" : "query_phase_execution_exception",          "reason" : "Result window is too large, from + size must be less than or equal to: [10000] but was [10010]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."

}

}

]

},  "status" : 500}

问了谷哥后发现,是由于ElasticSearch的默认 深度翻页 机制的限制造成的。ES默认的分页机制一个不足的地方是,比如有5010条数据,当你仅想取第5000到5010条数据的时候,ES也会将前5000条数据加载到内存当中,所以ES为了避免用户的过大分页请求造成ES服务所在机器内存溢出,默认对深度分页的条数进行了限制,默认的最大条数是10000条,这是正是问题描述中当获取第10000条数据的时候报Result window is too large异常的原因。(因为页面为1001页的时候后台1001-1然后乘以10作为from的值取查询ES,而ES默认需要from+size要小于index.max_result_window: 最大窗口值)。

要解决这个问题,可以使用下面的方式来改变ES默认深度分页的index.max_result_window 最大窗口值curl -XPUT http://127.0.0.1:9200/dating_profile/_settings -d '{ "index" : { "max_result_window" : 50000}}'

这里的dating_profile为index。

其中my_index为要修改的index名,50000为要调整的新的窗口数。

作者:我的小碗汤

链接:https://www.jianshu.com/p/06307c57c1fd

珍爱网html模板,爬取珍爱网后用户信息展示相关推荐

  1. python爬虫知网实例-python爬取知网

    广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! https:github.comgnemougdistribute_crawler ...

  2. 如何爬取了知乎用户信息,并做了简单的分析

    转载请标明出处: http://blog.csdn.net/forezp/article/details/68951699 本文出自方志朋的博客 一.使用的技术栈: 爬虫:python27 +requ ...

  3. 如何一小时爬取百万知乎用户信息,并做简单的可视化分析?

    一.使用的技术栈: 爬虫:python27 +requests+json+bs4+time 分析工具: ELK套件 开发工具:pycharm 二.数据成果 三.简单的可视化分析 1.性别分布 0 绿色 ...

  4. python爬取知乎live_Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)...

    classZhihuSpider(scrapy.Spider): name= "zhihu"allowed_domains= ["www.zhihu.com"] ...

  5. 用go语言爬取珍爱网 | 第一回

    我们来用go语言爬取"珍爱网"用户信息. 首先分析到请求url为: http://www.zhenai.com/zhenghun 接下来用go请求该url,代码如下: packag ...

  6. selenium爬取珍爱网用户信息

    近期接到一个任务,爬取珍爱网上的用户信息,这个对单身的我来说瞬间提起了兴趣,这有可能是我脱单的开始,哼哼,不装逼了,先来看看怎么帮我脱单,嘻嘻嘻 import requests import time ...

  7. 用python爬取基金网信息数据,保存到表格,并做成四种简单可视化。(爬虫之路,永无止境!)

    用python爬取基金网信息数据,保存到表格,并做成四种简单可视化.(爬虫之路,永无止境!) 上次 2021-07-07写的用python爬取腾讯招聘网岗位信息保存到表格,并做成简单可视化. 有的人留 ...

  8. Scrapy爬取当当网的商品信息存到MySQL数据库

    Scrapy爬取当当网的商品信息存到MySQL数据库 Scrapy 是一款十分强大的爬虫框架,能够快速简单地爬取网页,存到你想要的位置.经过两天的摸索,终于搞定了一个小任务,将当当网的商品信息爬下来存 ...

  9. 在当当买了python怎么下载源代码-python爬虫爬取当当网

    [实例简介]python爬虫爬取当当网 [实例截图] [核心代码] ''' Function: 当当网图书爬虫 Author: Charles 微信公众号: Charles的皮卡丘 ''' impor ...

最新文章

  1. 将横排文本变成竖排文本
  2. STL的deque容器
  3. (转)几种常用存储过程分页方法
  4. 滴滴2017在线笔试有感
  5. Markdown入门
  6. 使用Architecture Explorer分析应用程序及使用层次图
  7. PIP 安装 numpy
  8. c语言平均绩点_如何靓化你的GPA
  9. 【干货】PPT宝典:结构化思考,图形化表达.pdf(附下载链接)
  10. 酷软 正在连接服务器,酷软一直显示正在连接服务器...系统日志有大量错误信息...
  11. Resnet18详细结构
  12. 数据结构算法——1006. 线性链表的插入与删除
  13. html如何设置提示收到消息,从零开始实现一个消息提示框
  14. 两个超实用的 Kubernetes 集群中 Flannel 故障排除案例
  15. 分享一个英语听力资源下载网站
  16. [leetcode] 309. Best Time to Buy and Sell Stock with Cooldown 解题报告
  17. C++ 两点之间最短距离
  18. 一名IT界“老”技术人关于学习与成长的分享,受益!
  19. c语言中用rgb改颜色字体,C语言颜色转换宏
  20. hex文件详解及常用合并方法介绍

热门文章

  1. 管理员index页面初始化所需的父类操作
  2. 【电气专业知识问答】问:直流回路中为何严禁使用交流空气断路器?
  3. 高速公路桥梁路段安全形势及管理对策研究
  4. 豚鼠努力学习前端第二周
  5. 分词工具使用系列——sentencepiece使用
  6. 与天斗,与地斗,与人斗,其乐无穷!!!
  7. 详解僵尸进程、进程等待
  8. HackTheGame 攻略 - 第十关
  9. 对学习过程中的认知和体会
  10. uni-app自适应刘海屏