75142913在线留言
GO colly写的一个建立WEB服务通过传参爬取指定URL_Go语言_网络人

GO colly写的一个建立WEB服务通过传参爬取指定URL

Kwok 发表于:2021-01-07 09:07:56 点击:5 评论: 0

最近在学习GO colly爬取页面,因为我的CMS需要在用户访问的时候被动生成HTML,最近2天又在学习GO colly爬虫框架,就写了一个爬取自己网站生成HTML的小工具。

一、先上代码(代码已做了注释):

package main

/*
 * 在本机建立一个HTTP服务,通过get的url参数传入网址统计当前页面的链接地址
 *
 */
import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"regexp"
	"strings"

	"github.com/gocolly/colly"
)

//pageInfo 连接页面属性
type pageInfo struct {
	StatusCode int            //状态码
	Links      map[string]int //连接重复数
}

//ReplaceDomain 将域名前后缀清除
func ReplaceDomain(s string) string {
	//解析正则表达式,如果成功,返回解释器
	re := regexp.MustCompile(`://([^s]*?)/`)
	if re == nil {
		fmt.Println("正则匹配错误")
		return ""
	}
	newURL := re.FindStringSubmatch(s)
	return newURL[1]
	/* 上面的代码效率才高哦~之所以保留下面的,是因为我走了弯路
	s = re.FindString(s) //根据正则提取域名信息,如://www.neter8.com/
	replace := [...]string{"://", "/"}
	for _, v := range replace {
		s = strings.ReplaceAll(s, v, "")
	}
	return s
	*/
}

//handler HTTP服务器
func handler(w http.ResponseWriter, r *http.Request) {
	URL := r.URL.Query().Get("url")     //获取get方法的url参数为爬取的网址
	field := r.URL.Query().Get("field") //获取get方法的限制字段
	if URL == "" {
		fmt.Fprint(w, "url参数为必填项,例如:http://127.0.0.1:8080/?url=http://www.neter8.com/&field=action-") //URL里出现了action-才爬取
		return
	}
	log.Println("开始访问:", URL)
	c := colly.NewCollector(
		colly.AllowedDomains(ReplaceDomain(URL)), //限制域名为提交的url
		//colly.Async(true),                    //异步访问好像有问题,会出现map并发读取的情况,暂时注释掉了
	) //初始化爬虫并限制抓取域名
	p := &pageInfo{Links: make(map[string]int)} //初化定义一个页面属性

	// 统计链接数
	c.OnHTML("a[href]", func(e *colly.HTMLElement) {
		link := e.Request.AbsoluteURL(e.Attr("href")) //获取链接的绝对地址
		if link != "" {
			p.Links[link]++ //链接在页面上的出现次数
			if field == "" {
				c.Visit(link) //第二层爬取
			} else {
				//按链接里出现的关键字(field)条件抓取
				if strings.Contains(link, field) {
					log.Println("抓取链接:", link)
					c.Visit(link) //第二层爬取
				}
			}
		}
	})

	// 提取状态代码
	c.OnResponse(func(r *colly.Response) {
		log.Println("收到状态码:", r.Request.URL, r.StatusCode)
		p.StatusCode = r.StatusCode //当前页面的状态码(URL)
	})
	c.OnError(func(r *colly.Response, err error) {
		log.Println("出现错误:", r.StatusCode, err)
		p.StatusCode = r.StatusCode
	})

	c.Visit(URL)
	//c.Wait() //等待线程完成,开启异步时需要
	//输出结果
	b, err := json.Marshal(p) //把抓取到的链接转为json格式
	if err != nil {
		log.Println("未能序列化,错误详细:", err)
		return
	}
	w.Header().Add("Content-Type", "application/json")
	w.Write(b)
}

func main() {
	// 使用方法: curl -s 'http://127.0.0.1:8080/?url=http://www.neter8.com/'
	addr := ":8080"
	http.HandleFunc("/", handler)
	log.Printf("本地HTTP服务器已启动,请访问:http://127.0.0.1%s/?url=http://www.neter8.com/&field=action-测试", addr)
	log.Fatal(http.ListenAndServe(addr, nil))
}

GO colly 是一个很优秀的爬虫框架,后续的内容我将会详细的介绍使用笔记。

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:http://www.neter8.com/go/97.html
标签:collyKwok最后编辑于:2021-01-09 14:09:08
3
感谢打赏!

《GO colly写的一个建立WEB服务通过传参爬取指定URL》的网友评论(0)

本站推荐阅读

热门点击文章