Golang爬虫及正则表达式的实现示例

目录
  • 字符
  • 数量限定
  • 其他
  • 爬虫
  • 补充:正则表达式加golang爬虫爬取经典案例豆瓣top250

最近学习go,爬取网站数据用到正则表达式,做个总结;

Go中正则表达式采用RE2语法(具体是啥咱也不清楚);

字符

  • . ——匹配任意字符 e.g: abc. 结果: abcd,abcx,abc9;
  • [] ——匹配括号中任意一个字符 e.g: [abc]d 结果:ad,cd,1d;
  • - ——[-]中表示范围 e.g: [A-Za-z0-9];
  • ^ ——[^]中表示除括号中的任意字符 e.g:[^xy]a 结果:aa,da,不能为xa,ya;

数量限定

  • ? ——前面单元匹配0或1次;
  • + ——前面单元匹配1或多次;
  • * ——前面单元匹配0或多次;
  • {,} ——显示个数上下线;e.g : ip地址——[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3};

其他

  • \ ——转义字符;
  • | ——条件或;
  • () ——组成单元 如果字符串本身有括号"[(] aaa. [)]" ;

方法

//参数正则字符串,返回值*Regexp
str := regexp.MustCompile(string)
//参数要查找的数据,查找次数-1为全局,返回值二维数组,查找出的字符串+正则字符串
var result [][]string = str.FindAllStringSubmatch(data, -1)

爬虫

爬取博客园所有文章阅读量,评论,推荐;

package main

import (
 "fmt"
 "io"
 "net/http"
 "regexp"
 "strconv"
)

var readCount int = 0
var commentCount int = 0
var diggCount int = 0

//http读取网页数据写入result返回
func HttpGet(url string) (result string, err error) {
 resp, err1 := http.Get(url)
 if err1 != nil {
  err = err1
  return
 }
 defer resp.Body.Close()

 buf := make([]byte, 4096)

 for {
  n, err2 := resp.Body.Read(buf)
  //fmt.Println(url)
  if n == 0 {
   break
  }
  if err2 != nil && err2 != io.EOF {
   err = err2
   return
  }
  result += string(buf[:n])
 }
 return result, err
}

//横向纵向爬取文章标题数据,并累计数值
func SpiderPageDB(index int, page chan int) {
 url := "https://www.cnblogs.com/littleperilla/default.html?page=" + strconv.Itoa(index)

 result, err := HttpGet(url)

 if err != nil {
  fmt.Println("HttpGet err:", err)
  return
 }

 str := regexp.MustCompile("post-view-count\">阅读[(](?s:(.*?))[)]</span>")
 alls := str.FindAllStringSubmatch(result, -1)
 for _, j := range alls {
  temp, err := strconv.Atoi(j[1])
  if err != nil {
   fmt.Println("string2int err:", err)
  }
  readCount += temp
 }

 str = regexp.MustCompile("post-comment-count\">评论[(](?s:(.*?))[)]</span>")
 alls = str.FindAllStringSubmatch(result, -1)
 for _, j := range alls {
  temp, err := strconv.Atoi(j[1])
  if err != nil {
   fmt.Println("string2int err:", err)
  }
  commentCount += temp
 }

 str = regexp.MustCompile("post-digg-count\">推荐[(](?s:(.*?))[)]</span>")
 alls = str.FindAllStringSubmatch(result, -1)
 for _, j := range alls {
  temp, err := strconv.Atoi(j[1])
  if err != nil {
   fmt.Println("string2int err:", err)
  }
  diggCount += temp
 }

 page <- index
}

//主要工作方法
func working(start, end int) {
 fmt.Printf("正在从%d到%d爬取中...\n", start, end)

 //channel通知主线程是否所有go都结束
 page := make(chan int)

 //多线程go程同时爬取
 for i := start; i <= end; i++ {
  go SpiderPageDB(i, page)
 }

 for i := start; i <= end; i++ {
  fmt.Printf("拉取到%d页\n", <-page)
 }
}

//入口函数
func main() {
 //输入爬取的起始页
 var start, end int
 fmt.Print("startPos:")
 fmt.Scan(&start)
 fmt.Print("endPos:")
 fmt.Scan(&end)

 working(start, end)

 fmt.Println("阅读:", readCount)
 fmt.Println("评论:", commentCount)
 fmt.Println("推荐:", diggCount)
}

补充:正则表达式加golang爬虫爬取经典案例豆瓣top250

package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"regexp"
	"strconv"
)

func savToFile(index int, filmName, filmScore [][]string) {
	f, err := os.Create("第" + strconv.Itoa(index) + "页.txt")
	if err != nil {
		fmt.Println("os create err", err)
		return
	}
	defer f.Close()
	// 查出有多少条
	n := len(filmName)
	// 先写抬头 名称     评分
	f.WriteString("电影名称" + "\t\t\t" + "评分" + "\n")
	for i := 0; i < n; i++ {
		f.WriteString(filmName[i][1] + "\t\t\t" + filmScore[i][1] + "\n")
	}
}

func main() {
	var start, end int
	fmt.Print("请输入要爬取的起始页")
	fmt.Scan(&start)
	fmt.Print("请输入要爬取的终止页")
	fmt.Scan(&end)
	working(start, end)
}

func working(start int, end int) {
	fmt.Printf("正在爬取%d到%d页", start, end)
	for i := start; i <= end; i++ {
		SpiderPage(i)
	}
}

// 爬取一个豆瓣页面数据信息保存到文档
func SpiderPage(index int) {
	// 获取url
	url := "https://movie.douban.com/top250?start=" + strconv.Itoa((index-1)*25) + "&filter="

	// 爬取url对应页面
	result, err := HttpGet(url)
	if err != nil {
		fmt.Println("httpget err", err)
		return
	}
	//fmt.Println("result=", result)
	// 解析,编译正则表达式  ---电影名称
	ret := regexp.MustCompile(`<img width="100" alt="(?s:(.*?))"`)
	filmName := ret.FindAllStringSubmatch(result, -1)
	for _, name := range filmName {
		fmt.Println("name", name[1])
	}

	ret2 := regexp.MustCompile(`<span class="rating_num" property="v:average">(?s:(.*?))<`)
	filmScore := ret2.FindAllStringSubmatch(result, -1)
	for _, score := range filmScore {
		fmt.Println("score", score[1])
	}

	savToFile(index, filmName, filmScore)

}

// 爬取指定url页面,返回result
func HttpGet(url string) (result string, err error) {
	req, _ := http.NewRequest("GET", url, nil)
	// 设置头部信息
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36 OPR/66.0.3515.115")
	resp, err1 := (&http.Client{}).Do(req)
	//resp, err1 := http.Get(url)  //此方法已经被豆瓣视为爬虫,返回状态吗为418,所以必须伪装头部用上述办法
	if err1 != nil {
		err = err1
		return
	}
	defer resp.Body.Close()

	buf := make([]byte, 4096)

	//循环爬取整页数据
	for {
		n, err2 := resp.Body.Read(buf)
		if n == 0 {
			break
		}
		if err2 != nil && err2 != io.EOF {
			err = err2
			return
		}
		result += string(buf[:n])
	}

	return

}

到此这篇关于Golang爬虫及正则表达式的实现示例的文章就介绍到这了,更多相关Golang爬虫及正则表达式 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言并发爬虫的具体实现

    目录 写在前面 1. 单线程爬虫 2. 多线程爬虫 2.1 channel main函数 2.2 sync.WaitGroup 3. 源码地址 写在前面 这篇文章主要让大家明白多线程爬虫,因为go语言实现并发是很容易的. 这次的服务端,是我们之前搭建的电子商城平台,所以我们不担心ip被封之类的问题. 而实际生产环境中,其实我们都是用python爬虫的.python实现多线程也很简单. 这次我们可以试试新玩法,试试go语言的并发爬虫. 主要是爬取第一页的商品,爬取十次,比较单线程和多线程的时间.

  • Go语言做爬虫状态码返回418的问题解决

    目录 背景 原因分析 代码部分 背景  在使用Go语言做爬虫时,使用http.Get(url)去获取网页内容,状态码返回404,Body体为空. 原因分析  http.Get(url)是不需要设置header属性的http请求,比较简单快捷,但状态码返回418,表明我们需要设置其header属性,那么我们可以使用http.NewRequest,在设置其header属性即可~ 代码部分 func main7() { client := &http.Client{} url := "http

  • Go语言实现的web爬虫实例

    本文实例讲述了Go语言实现的web爬虫方法.分享给大家供大家参考.具体分析如下: 这里使用 Go 的并发特性来并行执行 web 爬虫. 修改 Crawl 函数来并行的抓取 URLs,并且保证不重复. 复制代码 代码如下: package main import (     "fmt" ) type Fetcher interface {         // Fetch 返回 URL 的 body 内容,并且将在这个页面上找到的 URL 放到一个 slice 中.     Fetch(

  • Golang爬虫及正则表达式的实现示例

    目录 字符 数量限定 其他 爬虫 补充:正则表达式加golang爬虫爬取经典案例豆瓣top250 最近学习go,爬取网站数据用到正则表达式,做个总结: Go中正则表达式采用RE2语法(具体是啥咱也不清楚): 字符 . --匹配任意字符 e.g: abc. 结果: abcd,abcx,abc9; [] --匹配括号中任意一个字符 e.g: [abc]d 结果:ad,cd,1d: - --[-]中表示范围 e.g: [A-Za-z0-9]: ^ --[^]中表示除括号中的任意字符 e.g:[^xy]

  • Python爬虫之正则表达式基本用法实例分析

    本文实例讲述了Python爬虫之正则表达式基本用法.分享给大家供大家参考,具体如下: 一.简介 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列匹配某个句法规则的字符串.在很多文本编辑器里,正则表达式通常被用来检索.替换那些匹配某个模式的文本. compile 函数根据一个模式字符串和可选的标志参数生成一个正则表

  • Golang 限流器的使用和实现示例

    限流器是服务中非常重要的一个组件,在网关设计.微服务.以及普通的后台应用中都比较常见.它可以限制访问服务的频次和速率,防止服务过载,被刷爆. 限流器的算法比较多,常见的比如令牌桶算法.漏斗算法.信号量等.本文主要介绍基于漏斗算法的一个限流器的实现.文本也提供了其他几种开源的实现方法. 基于令牌桶的限流器实现 在golang 的官方扩展包 time 中(github/go/time),提供了一个基于令牌桶算法的限流器的实现. 原理 令牌桶限流器,有两个概念: 令牌:每次都需要拿到令牌后,才可以访问

  • Golang中的错误处理的示例详解

    目录 1.panic 2.包装错误 3.错误类型判断 4.错误值判断 1.panic 当我们执行panic的时候会结束下面的流程: package main import "fmt" func main() { fmt.Println("hello") panic("stop") fmt.Println("world") } 输出: go run 9.go hellopanic: stop 但是panic也是可以捕获的,我们可

  • 常用JavaScript正则表达式汇编与示例详解

    1.1 前言 目前收集整理了21个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IP地址. 十六进制颜色. 日期. 微信号.车牌号.中文正则等.表单验证处理必备,赶紧收藏吧! 还会陆续加入新的正则进来,大家多提宝贵意见! 2.1 用户名正则 2.1.1 基本用户名正则 在做用户注册时,都会用到用户名正则校验. 定义基本用户名命名规则如下: 最短4位,最长16位 {4,16} 可以包含小写大母 [a-z]

  • Python爬虫之正则表达式的使用教程详解

    正则表达式的使用 re.match(pattern,string,flags=0) re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none 参数介绍: pattern:正则表达式 string:匹配的目标字符串 flags:匹配模式 正则表达式的匹配模式: 最常规的匹配 import re content ='hello 123456 World_This is a Regex Demo' print(len(content)) resul

  • Golang实现web文件共享服务的示例代码

    本文主要介绍了Golang实现web文件共享服务的示例代码,分享给大家,具体如下: 很简单,只需要两行代码. http.Handle("/", http.FileServer(http.Dir("./"))) //把当前文件目录作为共享目录 http.ListenAndServe(":8080", nil) 这时候,通过浏览器打开 http://ip 地址:8080 就可以了. 也许这样就完了,但是我为了方便非程序员用户使用,还需要程序自动获取本

  • golang 获取明天零点的时间戳示例

    实例如下所示: package main import ( "fmt" "time" ) func main() { timeStr := time.Now().Format("2006-01-02") fmt.Println(timeStr) //使用Parse 默认获取为UTC时区 需要获取本地时区 所以使用ParseInLocation t, _ := time.ParseInLocation("2006-01-02 15:04:

  • SQL Anywhere正则表达式语法与示例

    正则表达式语法 通过 SIMILAR TO 和 REGEXP 搜索条件以及 REGEXP_SUBSTR 函数支持正则表达式.对于 SIMILAR TO,正则表达式语法符合 ANSI/ISO SQL 标准.对于 REGEXP 和 REGEXP_SUBSTR,正则表达式的语法和支持符合 Perl 5. REGEXP 和 SIMILAR TO 使用正则表达式是与字符串 相匹配,而 REGEXP_SUBSTR 使用正则表达式则是与子串 相匹配.要实现 REGEXP 和 SIMILAR TO 的子串匹配行

  • python使用selenium爬虫知乎的方法示例

    说起爬虫一般想到的情况是,使用 python 中都通过 requests 库获取网页内容,然后通过 beautifulSoup 进行筛选文档中的标签和内容.但是这样有个问题就是,容易被反扒机制所拦住. 反扒机制有很多种,例如知乎:刚开始只加载几个问题,当你往下滚动时才会继续往下面加载,而且在往下滚动一段距离时就会出来一个登陆的弹框. 这样的机制对于通过获取服务器返回内容的爬虫方式进行了限制,我们只能获得前几个回答,而没办法或许后面的回答. 所以需要使用 selenium 模拟真实浏览器进行操作.

随机推荐