编程语言go自带一系列的包,包括标准包和非标准子包,具体在这里描述https://golang.org/pkg/。
其中的标准包在下载go安装包就自带了,而有13个包是在go的源代码树之外的,需要使用go get命令进行下载安装。然而子包被移动到了github之上,使用go get命令时,第一障碍是被gfw阻断,第二障碍是URL重定向到https://godoc.org/,从而无法正常获取这些包。
这里使用爬取重定向内容的方法整理出最后需要执行的命令(无法自动执行,git进程以128错误号退出,有空再去解决了),其中C:\Users\xxx为GOPATH所指向的目录。
git clone --progress --recursive -v https://github.com/golang/benchmarks.git C:\Users\xxx\go\src\golang.org\x\benchmarks
git clone --progress --recursive -v https://github.com/golang/blog.git C:\Users\xxx\go\src\golang.org\x\blog
git clone --progress --recursive -v https://github.com/golang/build.git C:\Users\xxx\go\src\golang.org\x\build
git clone --progress --recursive -v https://github.com/golang/crypto.git C:\Users\xxx\go\src\golang.org\x\crypto
git clone --progress --recursive -v https://github.com/golang/debug.git C:\Users\xxx\go\src\golang.org\x\debug
git clone --progress --recursive -v https://github.com/golang/image.git C:\Users\xxx\go\src\golang.org\x\image
git clone --progress --recursive -v https://github.com/golang/mobile.git C:\Users\xxx\go\src\golang.org\x\mobile
git clone --progress --recursive -v https://github.com/golang/net.git C:\Users\xxx\go\src\golang.org\x\net
git clone --progress --recursive -v https://github.com/golang/sys.git C:\Users\xxx\go\src\golang.org\x\sys
git clone --progress --recursive -v https://github.com/golang/text.git C:\Users\xxx\go\src\golang.org\x\text
git clone --progress --recursive -v https://github.com/golang/tools.git C:\Users\xxx\go\src\golang.org\x\tools
git clone --progress --recursive -v https://github.com/golang/tour.git C:\Users\xxx\go\src\golang.org\x\tour
git clone --progress --recursive -v https://github.com/golang/exp.git C:\Users\xxx\go\src\golang.org\x\exp
程序代码如下:
package main
import (
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"net/http"
"os"
"strings"
)
func main(){
os.Setenv("HTTP_PROXY","127.0.0.1:8087")
os.Setenv("HTTPS_PROXY","127.0.0.1:8087")
urls:=GetSubrepo("https://golang.org/pkg/")
for i := 0;i<len(urls);i++{
url:=GetGithubUrl(urls[i])
cloneUrl:=GetCloneAddr(url)
repo:=cloneUrl[strings.LastIndex(cloneUrl,"/")+1:strings.LastIndex(cloneUrl,".git")]
GitClone(cloneUrl,os.Getenv("GOPATH")+"\\src\\golang.org\\x\\"+repo)
}
}
func GitClone(url string,target string){
command:="git clone --progress --recursive -v " + url + " " + target
fmt.Println(command)
//cmd:=exec.Command("git","clone","--progress","--recursive","-v",url,target)
//if out,err:=cmd.Output();err!=nil{
// //log.Fatal(err)
// fmt.Println(err)
// os.Exit(-1)
//}else{
// fmt.Println(out)
//}
}
func GetCloneAddr(url string) string{
doc:=GetHtmlDoc(url)
newurl :=""
doc.Find("input").Each(func(i int,s *goquery.Selection){
if v,_:=s.Attr("class");v=="form-control input-monospace input-sm"{
gv,_:=s.Attr("value")
newurl = gv
}
})
return newurl
}
func GetGithubUrl(url string) string{
doc:=GetHtmlDoc(url)
newurl:=""
doc.Find("div").Each(func(i int,s *goquery.Selection){
if id,_:=s.Attr("id");id == "x-projnav"{
result,_ := s.Children().First().Attr("href")
newurl = result
}
})
return newurl
}
func GetSubrepo(url string) []string{
doc := GetHtmlDoc(url)
result :=make([]string,0)
doc.Find("li").Each(func(i int,s *goquery.Selection){
if uri,_ := s.Children().First().Attr("href");strings.HasPrefix(uri,"//godoc.org/golang.org/x/"){
result = append(result,"https:"+uri)
}
})
return result
}
func GetHtmlDoc(url string) *goquery.Document{
resp,err:=http.Get(url)
if err!=nil{
log.Fatal(err)
return nil
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
log.Fatalf("status code error: %d %s", resp.StatusCode, resp.Status)
return nil
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Fatal(err)
return nil
}
return doc
}