K&

源码

 

目录结构

 

 

 

 

 

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()
}

 

posted on 2021-12-31 21:31  K&  阅读(309)  评论(0编辑  收藏  举报