源码
目录结构
package Createfile import ( "fmt" "log" "os" "os/exec" "sync" "time" ) //单例模式就是在这个函数下不论调用多少次只执行一次 var create sync.Once //检测目录目录 func createdir() { cmd := exec.Command("mkdir","OutPut") if _,cmderr := cmd.CombinedOutput();cmderr !=nil{ log.Println(cmderr) } } //创建文件并返回文件地址指针 func CreateFile() *os.File { create.Do(func() { //判断文件夹OutPut似乎否存在 f,err := os.Stat("OutPut") //IsExist认为正常文件存在时err是空返回时true,所以不存在就是去反所以需要加! if !os.IsExist(err){ //调用创建文件 createdir() } if f.IsDir(){ //存在的话判断是否是目录如果是报存在不是就创建 log.Println("OutPut目录已经存在") } createdir() }) //输出文件定义文件名字与方法 创建|写入|追加 权限0644 rw,r,r osfile,err := os.OpenFile("OutPut/geturl" + fmt.Sprintf("-%d%d%d%d%d%d.log", time.Now().Year(), time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second(), ),os.O_CREATE|os.O_WRONLY|os.O_APPEND,0644) if err != nil{ log.Println(err) } return osfile }
package Readfile import ( "io/ioutil" "log" ) func ReadFile(filename string) []byte { //读取文件返回文件内容 filebyte,fileerr := ioutil.ReadFile(filename) if fileerr != nil { log.Println(fileerr) } return filebyte }
package UrlGet import ( "fmt" "littletools/GetUrl/Createfile" . "littletools/GetUrl/Readfile" "log" "mvdan.cc/xurls/v2" "regexp" ) func UrlGet(filename string) { //为了方便把创建文件赋给file后面写省事 file := Createfile.CreateFile() //文件正常文件打开后用完记得关闭defer就是在函数返回前执行的语句可以理解为延迟执行 defer file.Close() //抓取url arraybyte := xurls.Relaxed().FindAll(ReadFile(filename), -1) for k, v := range arraybyte { //二次筛选不要的部分,其实可以直接筛选http/https开头的即可(这个玩法是保留要的) if match,err := regexp.MatchString(`(不要的正则部分){1}`,string(v));match{ if err!=nil{ log.Println(err) } continue } if match,err := regexp.MatchString(`(\.events)$`,string(v));match{ if err!=nil{ log.Println(err) } continue } //把结果写入到创建的文件中k是索引第几个的意思v就是url值,filename就是字面意思 file.WriteString(fmt.Sprintf("%s %d %s\n", filename, k, v)) } }
package main import ( "littletools/GetUrl/UrlGet" "os" "sync" ) //如果不用这个有可能发生协程执行完毕后直接就退出了,所以导致结果可能是空的 var wg sync.WaitGroup //给写入文件加锁,不然会发生并发不安全。也就是说文件因为协程不安全导致内容缺失 var lock sync.Mutex func main() { //输入的参数也就是geturl 文件名 if len(os.Args[1:]) > 0{ //遍历单个名字 for _, filename := range os.Args[1:] { wg.Add(1) //协程 go func(name string) { //解决协程不安全问题 lock.Lock() defer lock.Unlock() defer wg.Done() UrlGet.UrlGet(name) }(filename) } } //等待协程结束 wg.Wait() }
针对,生活我不是想赢。我只是不想输!