最近在学习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.55mx.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.55mx.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.55mx.com/'
addr := ":8080"
http.HandleFunc("/", handler)
log.Printf("本地HTTP服务器已启动,请访问:http://127.0.0.1%s/?url=http://www.55mx.com/&field=action-测试", addr)
log.Fatal(http.ListenAndServe(addr, nil))
}
GO colly 是一个很优秀的爬虫框架,后续的内容我将会详细的介绍使用笔记。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/97
《GO colly写的一个建立WEB服务通过传参爬取指定URL》的网友评论(0)