Golang爬虫示例包

文件结构

  1. 自己用Golang原生包封装了一个爬虫库,源码见go get -u -v github.com/hunterhug/go_tool/spider
  2. ---- data 存放数据
  3. ---- example 爬虫例子
  4. --- pedaily 投资界爬虫

使用说明:

  1. go get -u -v github.com/hunterhug/spiderexample

一.投资界爬虫pedaily(pedaily.cn)

  1. companysearch.exe可通过关键字查找一家机构的简单信息
  2. companytouzi.exe可通过公司代号查找一家机构的投资情况

关键字查找一家机构的简单信息

关键字查找一家机构的简单信息,代码如下:

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github.com/PuerkitoBio/goquery"
  6. "github.com/hunterhug/go_tool/spider"
  7. "github.com/hunterhug/go_tool/spider/query"
  8. "github.com/hunterhug/go_tool/util"
  9. "math"
  10. "os"
  11. "strings"
  12. )
  13. var client *spider.Spider
  14. var dir = "./data/company/raw"
  15. var dirdetail = "./data/company/detailraw"
  16. var dirresult = "./data/company/result"
  17. func main() {
  18. welcome()
  19. initx()
  20. mainx()
  21. //fmt.Printf("%#v", detail("http://zdb.pedaily.cn/company/show587/"))
  22. }
  23. func welcome(){
  24. fmt.Println(`
  25. ************************************************************
  26. 投资界关键字查找公司信息
  27. 1.输入关键字
  28. 首先翻页后抓取详情页信息保存在data文件夹中
  29. 2.查看结果
  30. 查看data/company/result中csv文件
  31. 作者:一只尼玛
  32. 联系:569929309
  33. Golang大法
  34. /*
  35. go get -u -v github.com/hunterhug/spiderexample
  36. go build *.go,然后点击exe运行或go run *.go
  37. */
  38. ************************************************************
  39. `)
  40. }
  41. func initx() {
  42. var e error = nil
  43. client, e = spider.NewSpider(nil)
  44. if e != nil {
  45. panic(e.Error())
  46. }
  47. util.MakeDir(dir)
  48. util.MakeDir(dirresult)
  49. util.MakeDir(dirdetail)
  50. }
  51. func mainx() {
  52. inputReader := bufio.NewReader(os.Stdin)
  53. for {
  54. fmt.Println("Please input kyword: ")
  55. //fmt.Scanln(&keyword)
  56. keyword, err := inputReader.ReadString('\n')
  57. keyword = strings.Replace(keyword, "\n", "", -1)
  58. keyword = trip(strings.Replace(keyword, "\r", "", -1))
  59. if err != nil {
  60. fmt.Println(err.Error())
  61. continue
  62. }
  63. e := util.MakeDir(dir + "/" + keyword)
  64. if e != nil {
  65. fmt.Println(e.Error())
  66. }
  67. //keyword := "投资管理股份有限公司"
  68. result, numt, e := featchcompany(keyword)
  69. if e != nil {
  70. fmt.Println(e.Error())
  71. continue
  72. }
  73. if len(result) == 0 {
  74. fmt.Println("empty")
  75. continue
  76. } else {
  77. num := int(math.Ceil(float64(numt) / 20.0))
  78. for i := 2; i <= num; i++ {
  79. temp, _, e := featchcompany(keyword + "/" + util.IS(i))
  80. if e != nil {
  81. fmt.Println(e.Error())
  82. } else {
  83. result = append(result, temp...)
  84. }
  85. }
  86. fmt.Printf("total comepany:%d\n", numt)
  87. txt := []string{}
  88. txt = append(txt, "公司名,英语名称,简称,详情URL,投资URL,资本类型,机构性质,注册地点,机构总部,投资阶段,成立时间,官网,简介,联系方式")
  89. for _, k := range result {
  90. detailr := detail(k["href"])
  91. stemp := k["title"] + "," + detailr["english"] + "," + k["abbr"] + "," + k["href"] + "," + k["hreft"] + "," + detailr["zitype"] + "," + detailr["jx"]
  92. stemp = stemp + "," + detailr["rloca"] + "," + detailr["tloca"] + "," + detailr["tstage"] + "," + detailr["date"] + "," + detailr["website"] + "," + detailr["desc"] + "," + detailr["contact"]
  93. fmt.Println(stemp)
  94. txt = append(txt, stemp)
  95. }
  96. e := util.SaveToFile(dirresult+"/"+keyword+".csv", []byte(strings.Join(txt, "\n")))
  97. if e != nil {
  98. fmt.Println(e.Error())
  99. }
  100. }
  101. fmt.Println("------------")
  102. }
  103. }
  104. func detail(url string) map[string]string {
  105. returnmap := map[string]string{
  106. "english": "", //英文名称
  107. "zitype": "", //资本类型
  108. "jx": "", //机构性质
  109. "rloca": "", //注册地点
  110. "tloca": "", //机构总部
  111. "tstage": "", //投资阶段
  112. "date": "", //成立时间
  113. "website": "", //官方网站
  114. "desc": "", //简介
  115. "contact": "", //联系方式
  116. }
  117. hashmd := util.Md5(url)
  118. keep := dirdetail + "/" + hashmd + ".html"
  119. body := []byte("")
  120. var e error = nil
  121. if util.FileExist(keep) {
  122. body, e = util.ReadfromFile(keep)
  123. } else {
  124. client.Url = url
  125. body, e = client.Get()
  126. }
  127. if e != nil {
  128. return returnmap
  129. }
  130. util.SaveToFile(keep, body)
  131. doc, e := query.QueryBytes(body)
  132. if e != nil {
  133. return returnmap
  134. }
  135. returnmap["english"] = trip(doc.Find(".info h2").Text())
  136. returnmap["contact"] = strings.Replace(trip(doc.Find("#contact").Text()), "\n", "<br/>", -1)
  137. returnmap["desc"] = strings.Replace(trip(doc.Find("#desc").Text()), "\n", "<br/>", -1)
  138. returnmap["website"] = trip(doc.Find("li.link a").Text())
  139. info := ""
  140. doc.Find(".info ul li").Each(func(i int, node *goquery.Selection) {
  141. temp:=node.Text()
  142. temp=trip(strings.Replace(temp,"\n","",-1))
  143. temp=strings.Replace(temp,"&nbsp;","",-1)
  144. temp=strings.Replace(temp," ","",-1)
  145. info=info+"\n"+temp
  146. })
  147. dudu := tripemptyl(strings.Split(info, "\n"))
  148. for _, r := range dudu {
  149. rr := strings.Split(r, ":")
  150. dd := ""
  151. if len(rr) == 2 {
  152. dd = rr[1]
  153. } else {
  154. continue
  155. }
  156. if strings.Contains(r, "资本类型") {
  157. returnmap["zitype"] = dd
  158. } else if strings.Contains(r, "机构性质") {
  159. returnmap["jx"] = dd
  160. } else if strings.Contains(r, "注册地点") {
  161. returnmap["rloca"] = dd
  162. } else if strings.Contains(r, "成立时间") {
  163. returnmap["date"] = dd
  164. } else if strings.Contains(r, "机构总部") {
  165. returnmap["tloca"] = dd
  166. } else if strings.Contains(r, "投资阶段") {
  167. returnmap["tstage"] = dd
  168. } else {
  169. }
  170. }
  171. return returnmap
  172. }
  173. func trip(s string) string {
  174. return strings.TrimSpace(strings.Replace(s, ",", "", -1))
  175. }
  176. func tripemptyl(dudu []string) []string {
  177. returnlist := []string{}
  178. for _, r := range dudu {
  179. if trip(r) != "" {
  180. returnlist = append(returnlist, trip(r))
  181. }
  182. }
  183. return returnlist
  184. }
  185. func featchcompany(keyword string) ([]map[string]string, int, error) {
  186. returnmap := []map[string]string{}
  187. url := "http://zdb.pedaily.cn/company/w" + keyword
  188. rootdir := strings.Split(keyword, "/")[0]
  189. hashmd := util.Md5(url)
  190. keep := dir + "/" + rootdir + "/" + hashmd + ".html"
  191. if util.FileExist(keep) {
  192. dudu, _ := util.ReadfromFile(keep)
  193. return parsecompany(dudu)
  194. }
  195. fmt.Printf("featch:%s\n", url)
  196. client.Url = url
  197. body, err := client.Get()
  198. if err != nil {
  199. return returnmap, 0, err
  200. }
  201. e := util.SaveToFile(keep, body)
  202. if e != nil {
  203. fmt.Println(url + ":" + e.Error())
  204. }
  205. return parsecompany(body)
  206. }
  207. func parsecompany(body []byte) ([]map[string]string, int, error) {
  208. returnmap := []map[string]string{}
  209. d, e := query.QueryBytes(body)
  210. if e != nil {
  211. return returnmap, 0, e
  212. }
  213. total := d.Find(".total").Text()
  214. num, e := util.SI(total)
  215. if e != nil {
  216. return returnmap, 0, nil
  217. }
  218. d.Find(".company-list li").Each(func(i int, node *goquery.Selection) {
  219. temp := map[string]string{}
  220. content := node.Find(".txt a.f16")
  221. abbr := content.Next().Text()
  222. title := content.Text()
  223. href, ok := content.Attr("href")
  224. if !ok {
  225. return
  226. } else {
  227. href = "http://zdb.pedaily.cn" + href
  228. }
  229. //location := node.Find(".txt .location").Text()
  230. //desc := strings.Replace(node.Find(".desc").Text(), ",", "", -1)
  231. //desc = strings.Replace(desc, "\n", "", -1)
  232. //desc = strings.TrimSpace(desc)
  233. //desc = strings.Replace(desc, "\r", "", -1)
  234. temp["title"] = title
  235. temp["abbr"] = abbr
  236. temp["href"] = href
  237. hreft := strings.Split(href, "show")
  238. if len(hreft) == 0 {
  239. return
  240. }
  241. temp["hreft"] = "http://zdb.pedaily.cn/company/" + hreft[len(hreft)-1] + "vc/"
  242. //temp["location"] = location
  243. //temp["desc"] = desc
  244. //fmt.Printf("%s,%s,%s,%s,%s\n", title, href, temp["hreft"], abbr, location)
  245. returnmap = append(returnmap, temp)
  246. })
  247. return returnmap, num, nil
  248. }

公司代号查找一家机构的投资情况

公司代号查找一家机构的投资情况代码如下:

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github.com/PuerkitoBio/goquery"
  6. "github.com/hunterhug/go_tool/spider"
  7. "github.com/hunterhug/go_tool/spider/query"
  8. "github.com/hunterhug/go_tool/util"
  9. "math"
  10. "os"
  11. "regexp"
  12. "strings"
  13. )
  14. var tclient *spider.Spider
  15. var tresult = "./data/companyt/result"
  16. var traw = "./data/companyt/raw"
  17. func main() {
  18. dudu()
  19. inittouzi()
  20. tmain()
  21. //b, _ := util.ReadfromFile(tresult + "/3392.html")
  22. //l := parsetouzi(b)
  23. //fmt.Printf("%#v", l)
  24. }
  25. func parset(body []byte) ([]string, string) {
  26. returnlist := []string{}
  27. doc, _ := query.QueryBytes(body)
  28. total := doc.Find(".total").Text()
  29. doc.Find("#inv-list li").Each(func(i int, node *goquery.Selection) {
  30. href, ok := node.Find("dt.view a").Attr("href")
  31. if !ok {
  32. return
  33. }
  34. href = "http://zdb.pedaily.cn" + href
  35. fmt.Printf("Inv: %s:%s\n", node.Find(".company a").Text(), href)
  36. returnlist = append(returnlist, href)
  37. })
  38. return returnlist, total
  39. }
  40. func inittouzi() {
  41. var e error = nil
  42. tclient, e = spider.NewSpider(nil)
  43. if e != nil {
  44. panic(e.Error())
  45. }
  46. util.MakeDir(tresult)
  47. util.MakeDir(traw)
  48. }
  49. func tmain() {
  50. inputReader := bufio.NewReader(os.Stdin)
  51. for {
  52. fmt.Println("Please input url: ")
  53. //fmt.Scanln(&keyword)
  54. keyword, err := inputReader.ReadString('\n')
  55. keyword = strings.Replace(keyword, "\n", "", -1)
  56. keyword = trip(strings.Replace(keyword, "\r", "", -1))
  57. if err != nil {
  58. fmt.Println(err.Error())
  59. continue
  60. }
  61. r, _ := regexp.Compile(`[\d]+`)
  62. mark := r.FindString(keyword)
  63. if mark == "" {
  64. fmt.Println("找不到")
  65. continue
  66. }
  67. urls := []string{}
  68. loop := []string{}
  69. loop = append(loop, "y-2004")
  70. tyear, _ := util.SI(util.TodayString(1))
  71. for i := 2014; i <= tyear; i++ {
  72. loop = append(loop, "y"+util.IS(i))
  73. }
  74. result := []map[string]string{}
  75. for _, pp := range loop {
  76. url := "http://zdb.pedaily.cn/company/" + mark + "/vc/" + pp
  77. body, e := fetchpage(url)
  78. if e != nil {
  79. fmt.Println(e.Error())
  80. continue
  81. } else {
  82. fmt.Println("fetch " + url)
  83. }
  84. //e = util.SaveToFile(tresult+"/"+mark+".html", body)
  85. //if e != nil {
  86. // fmt.Println(e.Error())
  87. //}
  88. l, t := parset(body)
  89. fmt.Printf("%s:total:%s\n", pp, t)
  90. total, e := util.SI(t)
  91. if e != nil {
  92. fmt.Println(e.Error())
  93. continue
  94. }
  95. if total == 0 {
  96. fmt.Println("empty")
  97. continue
  98. }
  99. urls = append(urls, l...)
  100. page := int(math.Ceil(float64(total) / 20.0))
  101. for i := 2; i <= page; i++ {
  102. url := "http://zdb.pedaily.cn/company/" + mark + "/vc/" + pp + "/" + util.IS(i)
  103. body, e = fetchpage(url)
  104. if e != nil {
  105. fmt.Println(e.Error())
  106. continue
  107. } else {
  108. fmt.Println("fetch " + url)
  109. }
  110. temp, _ := parset(body)
  111. urls = append(urls, temp...)
  112. }
  113. }
  114. if len(urls) == 0 {
  115. fmt.Println("empty")
  116. continue
  117. }
  118. //fmt.Printf("%#v\n", urls)
  119. for _, url := range urls {
  120. body := []byte("")
  121. var e error = nil
  122. keep := traw + "/" + util.Md5(url) + ".html"
  123. if util.FileExist(keep) {
  124. body, e = util.ReadfromFile(keep)
  125. } else {
  126. body, e = fetchpage(url)
  127. }
  128. if e != nil {
  129. fmt.Println(e.Error())
  130. continue
  131. } else {
  132. fmt.Println("fetch " + url)
  133. }
  134. util.SaveToFile(keep, []byte(body))
  135. dududu := parsetouzi(body)
  136. dududu["url"] = url
  137. result = append(result, dududu)
  138. }
  139. if len(result) == 0 {
  140. fmt.Println("empty")
  141. continue
  142. }
  143. s := []string{"页面,事件名称,融资方,投资方,金额,融资时间,轮次,所属行业,简介"}
  144. for _, jinhan := range result {
  145. s = append(s, jinhan["url"]+","+jinhan["name"]+","+jinhan["rf"]+","+jinhan["tf"]+","+jinhan["money"]+","+jinhan["date"]+","+jinhan["times"]+","+jinhan["han"]+","+jinhan["desc"])
  146. }
  147. util.SaveToFile(tresult+"/"+mark+".csv", []byte(strings.Join(s, "\n")))
  148. }
  149. }
  150. func parsetouzi(body []byte) map[string]string {
  151. returnmap := map[string]string{
  152. "name": "",
  153. "rf": "",
  154. "tf": "",
  155. "money": "",
  156. "date": "",
  157. "times": "",
  158. "han": "",
  159. "desc": "",
  160. }
  161. doc, _ := query.QueryBytes(body)
  162. returnmap["name"] = doc.Find(".info h1").Text()
  163. returnmap["desc"] = strings.Replace(trip(doc.Find("#desc").Text()), "\n", "<br/>", -1)
  164. info := ""
  165. doc.Find(".info ul li").Each(func(i int, node *goquery.Selection) {
  166. temp := node.Text()
  167. temp = trip(strings.Replace(temp, "\n", "", -1))
  168. temp = strings.Replace(temp, "&nbsp;", "", -1)
  169. temp = strings.Replace(temp, " ", "", -1)
  170. info = info + "\n" + temp
  171. })
  172. //fmt.Println(info)
  173. dudu := tripemptyl(strings.Split(info, "\n"))
  174. //fmt.Printf("%#v\n", dudu)
  175. for _, r := range dudu {
  176. rr := strings.Split(r, ":")
  177. dd := ""
  178. if len(rr) == 2 {
  179. dd = strings.Replace(rr[1], " ", "", -1)
  180. } else {
  181. continue
  182. }
  183. if strings.Contains(r, "融") && strings.Contains(r, "方") {
  184. returnmap["rf"] = dd
  185. } else if strings.Contains(r, "投") && strings.Contains(r, "方") {
  186. returnmap["tf"] = dd
  187. } else if strings.Contains(r, "金") && strings.Contains(r, "额") {
  188. returnmap["money"] = dd
  189. } else if strings.Contains(r, "融资时间") {
  190. returnmap["date"] = dd
  191. } else if strings.Contains(r, "轮") && strings.Contains(r, "次") {
  192. returnmap["times"] = dd
  193. } else if strings.Contains(r, "所属行业") {
  194. returnmap["han"] = dd
  195. } else {
  196. }
  197. }
  198. return returnmap
  199. }
  200. func fetchpage(url string) ([]byte, error) {
  201. tclient.Url = url
  202. return tclient.Get()
  203. }
  204. func trip(s string) string {
  205. return strings.TrimSpace(strings.Replace(s, ",", "", -1))
  206. }
  207. func tripemptyl(dudu []string) []string {
  208. returnlist := []string{}
  209. for _, r := range dudu {
  210. if trip(r) != "" {
  211. returnlist = append(returnlist, trip(r))
  212. }
  213. }
  214. return returnlist
  215. }
  216. func dudu() {
  217. fmt.Println(`
  218. ************************************************************
  219. 投资界根据公司查找投资案例
  220. 1.输入URL或者输入数字587等
  221. 如:http://zdb.pedaily.cn/company/587/vc/
  222. 2.查看结果
  223. 查看data/company/tresult中csv文件
  224. 作者:一只尼玛
  225. 联系:569929309
  226. Golang大法
  227. /*
  228. go get -u -v github.com/hunterhug/spiderexample
  229. go build *.go,然后点击exe运行或go run *.go
  230. */
  231. ************************************************************
  232. `)
  233. }

Golang爬虫示例包系列教程(一):pedaily.com投资界爬虫的更多相关文章

  1. [转]让你从零开始学会写爬虫的5个教程(Python)

    让你从零开始学会写爬虫的5个教程(Python)   写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个 ...

  2. 【原】iOSCoreAnimation动画系列教程(二):CAKeyFrameAnimation【包会】

    在上一篇专题文章[原]iOSCoreAnimation动画系列教程(一):CABasicAnimation[包会]中我们学习了iOS核心动画CoreAnimation中CABasicAnimation ...

  3. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  4. 《Python爬虫学习系列教程》学习笔记

    http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ...

  5. 用包来组织模型 -- Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. 在我们使用python manage.py ...

  6. python 爬虫系列教程方法总结及推荐

    爬虫,是我学习的比较多的,也是比较了解的.打算写一个系列教程,网上搜罗一下,感觉别人写的已经很好了,我没必要重复造轮子了. 爬虫不过就是访问一个页面然后用一些匹配方式把自己需要的东西摘出来. 而访问页 ...

  7. [转]《Python爬虫学习系列教程》

    <Python爬虫学习系列教程>学习笔记 http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多. ...

  8. 实战SpringCloud响应式微服务系列教程(第十章)响应式RESTful服务完整代码示例

    本文为实战SpringCloud响应式微服务系列教程第十章,本章给出响应式RESTful服务完整代码示例.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 1.搭建响应式RESTful服务. ...

  9. 《吐血整理》高级系列教程-吃透Fiddler抓包教程(34)-Fiddler如何抓取微信小程序的包-上篇

    1.简介 有些小伙伴或者是童鞋们说小程序抓不到包,该怎么办了???其实苹果手机如果按照宏哥前边的抓取APP包的设置方式设置好了,应该可以轻松就抓到包了.那么安卓手机小程序就比较困难,不是那么友好了.所 ...

随机推荐

  1. Codeforces Round #FF 446A DZY Loves Sequences

    预处理出每一个数字能够向后延伸多少,然后尝试将两段拼起来. C. DZY Loves Sequences time limit per test 1 second memory limit per t ...

  2. outlook 会议室

    原文:outlook 会议室 但是,里面的方法只能用于发送普通电子邮件.如果要发起会议之类的特殊邮件的话,可以C#调用Outlook API,自身的API. 创建项目后,为它添加.NET引用:“Mic ...

  3. Spring IOC之基于JAVA的配置

    基础内容:@Bean 和 @Configuration 在Spring中新的支持java配置的核心组件是 @Configuration注解的类和@Bean注解的方法. @Bean注解被用于表明一个方法 ...

  4. leetcode第21题--Generate Parentheses

    problem: Given n pairs of parentheses, write a function to generate all combinations of well-formed ...

  5. javascript图片延迟加载(转载)

    <!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content=&q ...

  6. 【转】Android Application 对象介绍

    What is Application Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application ...

  7. 自己动手实现Expression翻译器 – Part Ⅱ

    上一节我们了解了Linq查询大体上是如何运转的,并针对SQL表达式进行建模(DbExpression),这一节的重点在于如何将表达式转换为DbExpression. 可以说只要能生成结构清晰的DbEx ...

  8. DotNET应用架构设计指南 安全 运行管理和通讯策略

    DotNET应用架构设计指南(第三章:安全 运行管理和通讯策略(13-16)) 安全 运行管理和通讯策略 组织策略定义的规则是支配应用程序如何安全,如何管理,不同的应用程序组件是如何和另一组件及外部服 ...

  9. 使用指定格式的字符串变量格式化日期字符串,DateAndTime取时间间隔

    private void btn_GetTime_Click(object sender, EventArgs e) { lab_time.Text = DateTime.Now.ToString(& ...

  10. JS引擎

    在javax.script包下提供有关脚本引擎的类和接口,为我们定义了一系列的规范,达到可以在java应用程序中执行脚本语言编写的程序. javax.script包的主要功能有: 1.脚本执行:执行脚 ...