3 采集规则

3.1 Spider结构体

Spider结构体用于定义蜘蛛规则。

3.1.1 一条简单的蜘蛛规则

  1. func init() {
  2. BaiduSearch.AddMenu()
  3. }
  4. var BaiduSearch = &Spider{
  5. Name: "百度搜索",
  6. Description: "百度搜索结果 [www.baidu.com]",
  7. // Pausetime: [2]uint{uint(3000), uint(1000)},
  8. Keyword: CAN_ADD,
  9. UseCookie: false,
  10. RuleTree: &RuleTree{
  11. Root: func(self *Spider) {
  12. self.Aid("生成请求", map[string]interface{}{"loop": [2]int{0, 1}, "Rule": "生成请求"})
  13. },
  14. Trunk: map[string]*Rule{
  15. "生成请求": {
  16. AidFunc: func(self *Spider, aid map[string]interface{}) interface{} {
  17. for loop := aid["loop"].([2]int); loop[0] < loop[1]; loop[0]++ {
  18. self.AddQueue(map[string]interface{}{
  19. "Url": "http://www.baidu.com/s?ie=utf-8&nojc=1&wd=" + self.GetKeyword() + "&rn=50&pn=" + strconv.Itoa(50*loop[0]),
  20. "Rule": aid["Rule"],
  21. })
  22. }
  23. return nil
  24. },
  25. ParseFunc: func(self *Spider, resp *context.Response) {
  26. query := resp.GetDom()
  27. total1 := query.Find(".nums").Text()
  28. re, _ := regexp.Compile(`[\D]*`)
  29. total1 = re.ReplaceAllString(total1, "")
  30. total2, _ := strconv.Atoi(total1)
  31. total := int(math.Ceil(float64(total2) / 50))
  32. if total > self.MaxPage {
  33. total = self.MaxPage
  34. } else if total == 0 {
  35. Log.Printf("[消息提示:| 任务:%v | 关键词:%v | 规则:%v] 没有抓取到任何数据!!!\n", self.GetName(), self.GetKeyword(), resp.GetRuleName())
  36. return
  37. }
  38. // 调用指定规则下辅助函数
  39. self.Aid("生成请求", map[string]interface{}{"loop": [2]int{1, total}, "Rule": "搜索结果"})
  40. // 用指定规则解析响应流
  41. self.Parse("搜索结果", resp)
  42. },
  43. },
  44. "搜索结果": {
  45. //注意:有无字段语义和是否输出数据必须保持一致
  46. OutFeild: []string{
  47. "标题",
  48. "内容",
  49. "不完整URL",
  50. "百度跳转",
  51. },
  52. ParseFunc: func(self *Spider, resp *context.Response) {
  53. query := resp.GetDom()
  54. query.Find("#content_left .c-container").Each(func(i int, s *goquery.Selection) {
  55. title := s.Find(".t").Text()
  56. content := s.Find(".c-abstract").Text()
  57. href, _ := s.Find(".t >a").Attr("href")
  58. tar := s.Find(".g").Text()
  59. re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
  60. // title = re.ReplaceAllStringFunc(title, strings.ToLower)
  61. // content = re.ReplaceAllStringFunc(content, strings.ToLower)
  62. title = re.ReplaceAllString(title, "")
  63. content = re.ReplaceAllString(content, "")
  64. // 结果存入Response中转
  65. resp.AddItem(map[string]interface{}{
  66. self.OutFeild(resp, 0): strings.Trim(title, " \t\n"),
  67. self.OutFeild(resp, 1): strings.Trim(content, " \t\n"),
  68. self.OutFeild(resp, 2): tar,
  69. self.OutFeild(resp, 3): href,
  70. })
  71. })
  72. },
  73. },
  74. },
  75. },
  76. }

 

3.1.2 Spider成员属性

  1. Spider.Id
    编写规则时无需指定,为SpiderQueue自动设置;
  2. Spider.Name
    规则名称,必须设置,且须保证全局唯一,在Task任务分发及规则列表中调用;
  3. Spider.Description
    规则描述,将在规则列表中显示;
  4. Spider.Pausetime
    设置暂停时间Pausetime[0]~Pausetime[0]+Pausetime[1],一般在UI统一设置,无需在规则中设置;
  5. Spider.MaxPage
    在UI设置,规则中涉及采集页数控制时,调用该属性值;
  6. Spider.Keyword
    UI中自定义输入,如需使用该属性,则必须在规则中初始化该值为常量USE;
  7. Spider.UseCookie
    控制下载器的两种运行模式,为true时支持登录功能,为false时支持大量UserAgent随机轮换,需在规则中指定;
  8. Spider.Proxy
    代理服务器;
  9. Spider.RuleTree
    采集规则的核心部分,包含所有规则解析函数;
  10. Spider.RuleTree.Root
    规则树的树根,即采集规则的执行入口函数;
  11. Spider.RuleTree.Trunk
    规则树树干,map[string]*Rule类型,包含除入口函数外,所有解析规则;
  12. Spider.RuleTree.Trunk[“name”]Rule
    就像是树干上的树枝一样,它是规则树上的一条解析规则;
  13. Rule.OutFeild
    输出字段,在非数据库的输出方式(Excel/csv)中作为标题行,规则中提交结果时,字段名应依赖改字段,该条Rule有OutFeild与该条规则有无结果输出必须保持一致;
  14. Rule.ParseFunc
    下载内容的解析函数,有系统根据response指定Rule自动调用;
  15. Rule.AidFunc
    辅助函数,根据需要你可以自由定制各种处理方法,例如最常用的便是批量生成请求。

3.1.3 Spider中常用方法讲解

  1. func (self *Spider) AddMenu()
    将蜘蛛规则自身添加至蜘蛛规则列表;
  2. func (self Spider) AddOutFeild(respOrRuleName interface{}, feild string)
    动态追加OutFeild切片成员,速度不如静态字段快 respOrRuleName接受
    Response或string两种类型,为*Response类型时指定当前Rule;
  3. func (self *Spider) AddQueue(param map[string]interface{}) 向调度器添加请求;
  4. func (self *Spider) BulkAddQueue(urls []string, param map[string]interface{})
    批量添加同一类请求,要求除url不同外,其他请求参数相同;
  5. func (self Spider) Parse(ruleName string, resp context.Response)
    调用指定Rule下的ParseFunc方法;
  6. func (self *Spider) Aid(ruleName string, aid map[string]interface{}) interface{}
    调用指定Rule下的AidFunc方法;
  7. func (self Spider) OutFeild(respOrRuleName interface{}, index int) string
    获取指定Rule的OutFeild,respOrRuleName接受
    Response或string两种类型,为*Response类型时指定当前Rule;
  8. func (self *Spider) GetKeyword() string
    获取UI输入的自定义字符串;
  9. func (self *Spider) GetMaxPage() int
    获取UI输入的最大采集页数限制;
  10. func (self Spider) GetRules() map[string]Rule
    获取整个规则树;
  11. func (self *Spider) SetPausetime(pause [2]uint, runtime …bool)
    设置暂停时间 pause[0]~(pause[0]+pause[1]) 当且仅当runtime[0]为true时可覆盖现有值。