分享
  1. 首页
  2. 文章

Golang网页下载示例

dexterman · · 3076 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


package main
/*
 * 中文编码问题
 */
import (
	"errors"
	"flag"
	"fmt"
	query "github.com/PuerkitoBio/goquery"
	"golang.org/x/text/encoding/simplifiedchinese"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
)
var (
	np = runtime.NumCPU()
	_ = runtime.GOMAXPROCS(np)
)
var wg sync.WaitGroup
type Folder struct {
	Url string
	Dir string
}
type File struct {
	Url string
	Dir string
	Name string
}
func checkErr(err error) {
	if err != nil {
		fmt.Printf("%v\n", err.Error())
		os.Exit(1)
	}
}
func decodeToGBK(text string) (string, error) {
	dst := make([]byte, len(text)*2)
	tr := simplifiedchinese.GB18030.NewDecoder()
	nDst, _, err := tr.Transform(dst, []byte(text), true)
	if err != nil {
		return text, err
	}
	return string(dst[:nDst]), nil
}
func printEach(index int, item *query.Selection) {
	fmt.Println("Selection: ", item.Text())
}
func isDir(path string) bool {
	return strings.HasSuffix(path, "/")
}
func makeFolder(item *query.Selection, url, dir string) (f *Folder, err error) {
	tx := item.Text()
	href, ok := item.Attr("href")
	name, err := decodeToGBK(tx)
	if err != nil {
		return
	}
	if !ok {
		err = errors.New("makeFolder : " + tx + " href属性不存在")
		return
	}
	f = &Folder{Url: url + href, Dir: filepath.Join(dir, name)}
	return
}
func makeFile(item *query.Selection, url, dir string) (f *File, err error) {
	tx := item.Text()
	href, ok := item.Attr("href")
	if !ok {
		err = errors.New("makeFile : " + tx + " href属性不存在")
		return
	}
	name, err := decodeToGBK(tx)
	if err != nil {
		return
	}
	f = &File{Url: url + href, Dir: dir, Name: name}
	return
}
func crawl(url, localDir string) {
	doc, err := query.NewDocument(url)
	// checkErr(err)
	if err != nil {
		fmt.Printf("%v\n", err.Error())
		return
	}
	items := doc.Find("a")
	dir := localDir
	if !strings.HasSuffix(url, "/") {
		url += "/"
	}
	crawlEach := func(i int, item *query.Selection) {
		tx := item.Text()
		if isDir(tx) {
			folder, err := makeFolder(item, url, dir)
			if err != nil {
				fmt.Printf("%v\n", err.Error())
				return
			}
			wg.Add(1)
			go crawlFolder(folder)
		} else {
			file, err := makeFile(item, url, dir)
			if err != nil {
				fmt.Printf("%v\n", err.Error())
				return
			}
			download(file)
		}
	}
	items.Each(crawlEach)
}
func download(file *File) {
	dir := file.Dir
	url := file.Url
	name := file.Name
	if err := os.MkdirAll(dir, os.ModePerm); os.IsExist(err) {
		fmt.Printf("%x is exist\n", dir)
	} else {
		os.Chmod(dir, os.ModePerm)
	}
	resp, err := http.Get(url)
	if err != nil {
		fmt.Printf("%v\n", err.Error())
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("%v\n", err.Error())
		return
	}
	fp := string([]rune(filepath.Join(dir, name)))
	err = ioutil.WriteFile(fp, body, 0777)
	if err != nil {
		fmt.Printf("%v fp:[%v]\n", err.Error(), fp)
		return
	}
	fmt.Printf("Download: %+v\n", file)
}
func crawlFolder(folder *Folder) {
	url := folder.Url
	dir := folder.Dir
	crawl(url, dir)
	wg.Done()
}
func main() {
	host := flag.String("host", "http://localhost:8000", "HTTP服务地址Host")
	location := flag.String("locate", "E:/Crawler下载文件", "本地文件系统绝对路径")
	flag.Parse()
	crawl(*host, *location)
	wg.Wait()
}





(追記) (追記ここまで)

有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:dexterman

查看原文:Golang网页下载示例

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3076 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏