unpkg 下载文件 小工具

概况

golang写个小程序把unpkg网站上的包下载下来,文章后面有现成exe程序。拿来就用,不要浪费时间。

目标

从unpkg.com中下载文件

原理分析

F12,启动!
在这里插入图片描述
发现网站文件目录信息全部存放在一个window.__DATA__的变量里。
在这里插入图片描述
可以发现他的数据也是有规则的,列表信息存放在target.details里面。里面甚至有type字段用来区分文件还是目录。
这下就好办啦。

实现思路

在这里插入图片描述

技术选型

golang
原因是方便编译成exe供后人使用

代码实现

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
)

type PageData struct {
	FileName       string `json:"filename"`
	PackageName    string `json:"packageName"`
	PackageVersion string `json:"packageVersion"`
	Target         Target `json:"target"`
}

type Target struct {
	Path    string           `json:"path"`
	Type    string           `json:"type"`
	Details map[string]AItem `json:"details"`
}

type AItem struct {
	Path        string `json:"path"`
	Type        string `json:"type"`
	ContentType string `json:"contentType"`
	Integrity   string `json:"integrity"`
	Size        int    `json:"size"`
}

func GetHtml(url string) string {
	//获取html
	resp, err := http.Get(url)
	resp.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")
	resp.Header.Set("Content-Type", "text/html;Charset=utf-8")
	resp.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36")

	if err != nil {
		fmt.Println("请求失败:", err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("读取响应失败:", err)
	}
	return string(body)
}

func DownloadFile(downloadUrl, dest, fileName string) error {
	//创建文件
	out, err := os.Create(dest + fileName)
	if err != nil {
		fmt.Println("创建文件失败", dest+fileName)
		return err
	}
	defer out.Close()
	//下载文件
	resp, err := http.Get(downloadUrl)
	if err != nil {
		fmt.Println("网络异常~!")
		return err
	}
	defer resp.Body.Close()
	//拷贝
	_, err = io.Copy(out, resp.Body)
	if err != nil {
		fmt.Println("网络异常~!")
		return err
	}

	return nil
}

func GetPageDataByUrl(url string, fileDir string) {
	str := GetHtml(url)
	ret := regexp.MustCompile(`window.__DATA__ =(.+?)</script>`)
	//只查找前 n 个匹配项,如果 n = -1,则查找所有匹配项
	//FindAllStringSubmatch 匹配结果:string1: 表示带有匹配参考项的全部字串。string2: 表示去除匹配参考项后的字串。
	res := ret.FindAllStringSubmatch(str, 1)
	pageData := PageData{}
	if len(res) != 1 || len(res[0]) != 2 {
		fmt.Println("数据获取失败", url)
		return
	}
	//解析json
	err := json.Unmarshal([]byte(res[0][1]), &pageData)
	if err != nil {
		fmt.Println("json解析失败")
		return
	}
	//无内容,进入到空目录
	if pageData.Target.Details == nil {
		return
	}
	//创建文件夹
	fmt.Println(fileDir + pageData.FileName)
	ferr := os.MkdirAll(fileDir+pageData.FileName, 0755)
	if ferr != nil {
		fmt.Println("文件夹创建失败", err)
		return
	}
	//递归
	for _, v := range pageData.Target.Details {
		var fileType = v.Type
		var fileName = v.Path

		if fileType == "file" {
			//文件 下载
			df := "https://unpkg.com/" + pageData.PackageName + "@" + pageData.PackageVersion + fileName
			fmt.Println(fileDir + fileName)
			derr := DownloadFile(df, fileDir, fileName)
			for derr != nil {
				derr = DownloadFile(df, fileDir, fileName)
			}
		} else {
			//目录 继续往下递归
			dd := "https://unpkg.com/browse/" + pageData.PackageName + "@" + pageData.PackageVersion + fileName + "/"
			GetPageDataByUrl(dd, fileDir)
		}
	}
}
func main() {
	var url string
	// url := "https://unpkg.com/browse/element-ui@2.15.14/"
	fmt.Println("请输入地址(eg:https://unpkg.com/browse/element-ui@2.15.14/)")
	fmt.Print("=>")
	fmt.Scan(&url)
	fmt.Println("=>准备执行...")
	var fileDir = "./keke_file"
	GetPageDataByUrl(url, fileDir)
	fmt.Println("=>执行完毕,文件已下载至" + fileDir)
}

运行

在这里插入图片描述
等个十来分钟(时间有点久,留给后人优化)
在这里插入图片描述
完成!!芜湖

附上源码地址,含exe可执行文件

https://gitee.com/cyme/go-unpkg-tool
链接: 网站unpkg.com,文件下载工具,实现语言:golang,有现成exe直接运行

在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值