您现在的位置是:首页 > 经验记录>日常笔记>使用Golang写一个站点的sitemap生成工具,可命令指定站点url,输出地址,并发数等 网站首页 日常笔记
使用Golang写一个站点的sitemap生成工具,可命令指定站点url,输出地址,并发数等
使用包:
"flag"
"github.com/PuerkitoBio/goquery"
"github.com/douyacun/gositemap"
"github.com/gocolly/colly"
"github.com/gocolly/colly/extensions"
"regexp"
"time"
思路:
一、基于gocolly/colly遍历全站,且通过正则限制仅遍历指定网站链接内路径。 通过PuerkitoBio/goquery匹配页面 href循环遍历 二、使用douyacun/gositemap进行sitemap xml生成
代码如下:
package main import ( "flag" "fmt" "github.com/PuerkitoBio/goquery" "github.com/douyacun/gositemap" "github.com/gocolly/colly" "github.com/gocolly/colly/extensions" "regexp" "time" ) var priority float64 = 1 func main() { //命令参数获取 targetUrl := flag.String("url","","目标站点地址") path := flag.String("path","","目标站点地址") Parallelnum := flag.Int("parallel",500,"并发数") Delay := flag.Int("delay",0,"延迟(毫秒)") MaxLinks := flag.Int("maxlink",50000,"最大链接数") //[必须调用]:从 arguments 中解析注册的 flag,不然参数获取都没值 flag.Parse() //参数验证 if len(*targetUrl) == 0{ panic("请传递目前站点地址") } if len(*path) == 0{ *path = fmt.Sprintf("gositemap/%s/",time.Now().Format("20060102_150405")) } st := gositemap.NewSiteMap() st.SetDefaultHost(*targetUrl) st.SetPretty(true) // 每个sitemap文件不能多于50000个链接,这里可以自己配置每个文件最多,如果超过MaxLinks,会自动生成sitemap_index.xml文件 st.SetMaxLinks(*MaxLinks) //xml文件输出地址 st.SetPublicPath(*path) t := time.Now() number := 1 //初始化 创建收集器 c := colly.NewCollector(func(c *colly.Collector) { extensions.RandomUserAgent(c) // 设置随机头 c.Async = true }, //过滤url,去除外链 colly.URLFilters( //regexp.MustCompile("^(https://www\\.uppdd\\.com/)"), regexp.MustCompile("^("+*targetUrl+"/(.*))"), ), ) //控制下速度 c.Limit(&colly.LimitRule{ //DomainGlob: "*uppdd.*", //过滤规则的作用域,不限制则全部链接皆使用该规则 DomainGlob: "*", Parallelism: *Parallelnum, Delay: time.Duration(*Delay), }) // 响应的格式为HTML,提取页面中的链接 c.OnHTML("a[href]", func(e *colly.HTMLElement) { link := e.Attr("href") href := e.Request.AbsoluteURL(link) // 访问url 内部会检查 是否符合 正则表达式 。如果不符合 终止访问该url c.Visit(href) }) c.OnHTML("body", func(e *colly.HTMLElement) { e.DOM.Each(func(i int, selection *goquery.Selection) { //匹配数据(页面dom结构) href := e.Request.AbsoluteURL(e.Attr("href")) //写入链接 url := gositemap.NewUrl() url.SetLoc(href) url.SetLastmod(time.Now()) url.SetChangefreq(gositemap.Daily) //获取页面权重 url.SetPriority(getPriority(number)) st.AppendUrl(url) number += 1 fmt.Printf("计数:%d,链接:%s \n",number,href) }) }) c.OnError(func(response *colly.Response, err error) { //fmt.Println(err) }) c.Visit(*targetUrl+"/") c.Wait() fmt.Printf("连接收集花费时间:%s,收集链接:%d个", time.Since(t),number) //bt,err := st.ToXml() //if err != nil{ // fmt.Printf("异常:%v", err) // return //} //byte切片转string,好查看是否有错误 //btString := string(bt) //输出 //fmt.Println(btString) //生成文件导出 filePath,err := st.Storage() if err != nil { fmt.Printf("%v", err) return } fmt.Println(filePath) } //递减乱获取权重|很随意 func getPriority(num int) float64 { if num < 20{ return 1 } newS := float64(num)/priority numQ := int(newS) //fmt.Printf("权重:%d \n",numQ) if num >= numQ{ priority -= 0.01 } return priority }
---------------------------------------------分割线----------------------------------------------
使用(这里示例我只指定了目标地址,其他参数可看代码自行提供):
go run . -url=https://www.uppdd.com
结果:
... 计数:75,链接:https://www.uppdd.com/info?id=79 计数:76,链接:https://www.uppdd.com/info?id=115 计数:77,链接:https://www.uppdd.com/info?id=117 计数:78,链接:https://www.uppdd.com/info?id=90 计数:79,链接:https://www.uppdd.com/info?id=103 计数:80,链接:https://www.uppdd.com/info?id=83 计数:81,链接:https://www.uppdd.com/info?id=112 计数:82,链接:https://www.uppdd.com/module?module_id=6&page=1 计数:83,链接:https://www.uppdd.com/info?id=92 连接收集花费时间:9.0064424s,收集链接:83个sitemap.xml
随机推荐
- Laravel框架下,页面(包含大量echarts图表)html导出为PDF实现,可批量.
- cgywin安装phpredis
- 在 Laravel 中使用 基于Workerman 的Gateway-worker进行 socket 长连接通讯
- ubuntu下nginx环境php7.1安装ZipArchive
- 阿里云 Failed to download metadata for repo ‘AppStream‘(centos8放弃维护)
- php导出数据到excel,防止身份证等数字字符格式变成科学计数的方法
- uniapp安卓打包使用及获取签名方法,自生成证书
- 微信支付关于你只有p12文件时, 我们却需要pem文件怎么办?
- Laravel 项目上线的一些注意事项
- Golang获取命令行参数(通过命令行指定参数控制程序运行)
文章评论
未开放