前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang网页下载示例

Golang网页下载示例

原创
作者头像
大师级码师
修改于 2021-11-01 02:26:34
修改于 2021-11-01 02:26:34
78600
代码可运行
举报
文章被收录于专栏:大师级码师大师级码师
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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()
}</pre> 

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Golang】使用Golang编写Hugo发布器
有这么一种说法,懒人创造了世界。他们懒得走路,所以发明了汽车;懒得爬楼梯,所以发明了电梯;懒得扇扇子,所以发明了电风扇、空调。懒说明了怕麻烦,博主其实就是一个怕麻烦的人。博主的博客Garfield-加菲的博客就是通过Hugo自动生成的静态网站,首先强调一点,我喜欢Hugo,它使我能够专注于markdown的编写,其他一切事情都交给Hugo,这也符合我懒的特点。
DDGarfield
2022/06/23
9700
【Golang】使用Golang编写Hugo发布器
golang 学习笔记
go语言完整的定义的变量的方法为 var 变量名 类型=值,var name string ="fuwei",可以简写为name:="fuwei"(这种只能在函数内使用,无法再包内使用),
付威
2021/05/06
1.1K0
Golang之http编程
Go原生支持http。import("net/http") Go的http服务性能和nginx比较接近 几行代码就可以实现一个web服务 服务端http package main import ( "fmt" "net/http" ) func Hello(w http.ResponseWriter, r *http.Request) { fmt.Println("handle hello") fmt.Fprintf(w, "hello") } func Login(w
超蛋lhy
2018/08/31
4730
golang小工具download公众号文章或其他网页图片
直接运行main.go文件或者通过go build ./打成windows下的exe包或者在linux下打成downloadPic包直接运行
山行AI
2019/11/21
1.4K0
golang小工具download公众号文章或其他网页图片
Golang 新手可能会踩的 50 个坑【转】
译文:https://github.com/wuYin/blog/blob/master/50-shades-of-golang-traps-gotchas-mistakes.md
landv
2018/11/23
2.1K0
go语言goquery下载图片实例「建议收藏」
cd $GOPATH/bin 编译:go build crawl 运行:./crawl –img_path=/data/pic
全栈程序员站长
2022/07/25
3950
用go语言爬取珍爱网 | 第二回
昨天我们一起爬取珍爱网首页,拿到了城市列表页面,接下来在返回体城市列表中提取城市和url,即下图中的a标签里的href的值和innerText值。
我的小碗汤
2018/08/22
4800
用go语言爬取珍爱网 | 第二回
golang的xml、json解析
xml golang的xml处理主要应用Unmarshal、Marshal方法实现,解析一个xml到struct如下,首先是xml文件: <?xml version="1.0" encoding="u
用户1141560
2017/12/26
3.2K0
golang的xml、json解析
go语言微信公众号开发后台接口封装
业余时间做了个有意思的小功能,每天早上7点准时给发天气预报,每晚8点发布一条英语说说,提醒自己不能忘记学习。
杨永贞
2020/08/04
2.2K0
Go语言多线程爬虫与代理IP反爬
有个朋友想用Go语言编写一个多线程爬虫,并且使用代理IP来应对反爬措施。多线程在Go中通常是通过goroutine实现的,所以应该使用goroutine来并发处理多个网页的抓取。然后,代理IP的话,可能需要一个代理池,从中随机选择代理来发送请求,避免同一个IP被封锁。大体思路就是这样,具体看我下面实操吧。
华科云商小徐
2025/05/12
950
Rust vs Go:常用语法对比(六)
res has type *http.Response. buffer has type []byte. It is idiomatic and strongly recommended to check errors at each step.
fliter
2023/09/05
2350
Rust vs Go:常用语法对比(六)
golang 基础编程
map 是一种无序的键值对, 它是数据结构 hash 表的一种实现方式,类似 Python 中的字典
全栈程序员站长
2022/07/19
1.3K0
golang 基础编程
Golang语言调用百度帐号
1:你要注册一个开发者,创建应用,填写完基本信息之后就要填写回调地址了 2:选择右上角的管理控制台---选择左下角的 其他API -- 选择安全设置--授权回调页 3:测试代码 如下: package main import ( // 自己引包 ) type AccessToken struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` Sessi
李海彬
2018/03/21
7110
Golang 读、写文件
这种方式每次都会覆盖 test.txt内容,如果test.txt文件不存在会创建。
孤烟
2020/09/27
2.4K0
Go语言的多线程实现与应用案例
Go语言中的Goroutine是一种轻量级的线程,它比传统的操作系统线程更轻量级,更易于管理。Goroutine的创建和调度由Go语言的运行时系统自动管理,开发者只需关注业务逻辑的实现。
GeekLiHua
2024/08/30
2340
golang ioutil io工具
func ReadAll(r io.Reader) ([]byte, error)
copy_left
2019/08/23
7190
Go语言下载、安装、配置、使用
Go语言(Golang,The Go Programming Language),是谷歌2009发布的第二款开源编程语言。2009年7月份,谷歌曾发布了Simple语言,它是用来开发Android应用。
阳光岛主
2019/02/18
2K0
Go语言下载、安装、配置、使用
golang语言常见范式
最近花了一个星期的时间看完了《Go语言程序设计》这本书,这本书不愧是大师的作品,写得很好。看过之后对golang语言的理解更深刻了。下面将书中提到的一些关键语言范式记录下来以备忘。 常见范式 普通for循环 var s, sep string for i := 0; i < len(os.Args); i++ { s += sep + os.Args[i] sep = " " } fmt.Println(s) for配合range var s, sep string for _, arg
jeremyxu
2018/05/10
2.1K0
Golang语言执行linux命令行
这个在开发中会经常用到: package main import ( "fmt" "io/ioutil" "os/exec" "time" ) func run() { cmd := exec.Command("/bin/sh", "-c", "ping 127.0.0.1") _, err := cmd.Output() if err != nil { panic(err.Error()) } if err := cm
李海彬
2018/03/20
3.4K0
Rust vs Go:常用语法对比(八)
题目来自 Golang vs. Rust: Which Programming Language To Choose in 2023?[1] 141. Iterate in sequence over
fliter
2023/09/05
3540
Rust vs Go:常用语法对比(八)
相关推荐
【Golang】使用Golang编写Hugo发布器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验