[日常] Go语言圣经-匿名函数习题2

练习5.13: 修改crawl,使其能保存发现的页面,必要时,可以创建目录来保存这些页面。只保存来自原始域名下的页面。假设初始页面在golang.org下,就不
要保存vimeo.com下的页面。

package main

import (
        "fmt"
        "io"
        "io/ioutil"
        "links"
        "log"
        "net/http"
        "net/url"
        "os"
)
/*
练习5.13: 修改crawl,使其能保存发现的页面,必要时,可以创建目录来保存这些页面。只保存来自原始域名下的页面。假设初始页面在golang.org下,就不要保存vimeo.com下的页面。
*/
var sum int
func main() {
        breadthFirst(crawl, os.Args[1:])
}

/*
抓取页面的所有连接
*/
func crawl(url string) []string {
        sum++

        go save(url)
        fmt.Printf("%d|%s\n", sum, url)
        list, err := links.Extract(url)
        if err != nil {
                log.Print(err)
        }
        return list
}

/*
保存页面到文件
*/
func save(u string) bool {

        urlObj, _ := url.Parse(u)
        path := "/tmp/crawl/" + urlObj.Host
        if urlObj.Path == "" || urlObj.Path == "/" {
                urlObj.Path = "/index.html"
        }
        filename := path + urlObj.Path //重点注意文件名
        fmt.Println(filename)
        //打开文件
        f, _ := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0755)
        //读取链接
        resp, geterr := http.Get(u)

        if geterr != nil || resp.StatusCode != http.StatusOK {
                //resp.Body.Close()
                return false
        }
        body, _ := ioutil.ReadAll(resp.Body)
        //fmt.Println(body)
        //创建保存目录
        _, err := os.Stat(path)
        if err != nil {
                os.MkdirAll(path, 0755)
        }

        io.WriteString(f, string(body))
        resp.Body.Close()
        body = nil
        return true
}

/*
广度优先算法
*/
// breadthFirst calls f for each item in the worklist.
// Any items returned by f are added to the worklist.
// f is called at most once for each item.
func breadthFirst(f func(item string) []string, worklist []string) {
        seen := make(map[string]bool)
        for len(worklist) > 0 {
                items := worklist
                worklist = nil
                for _, item := range items {
                        if !seen[item] {
                                seen[item] = true
                                worklist = append(worklist, f(item)...)
                        }
                }
        }
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言圣经》是一本广受好评的教材,旨在帮助读者系统地学习和掌握Go语言。这本书以简明清晰的方式介绍了Go语言的各种特性、语法和用法,是入门和进阶者的理想选择。 首先,该书提供了对Go语言基础知识的全面介绍。它从简单到复杂地解释了Go语言的基本概念,诸如变量、函数、循环和条件语句等等。通过丰富的例子和练习,读者能够逐步理解和掌握这些概念。 其次,该书详细介绍了Go语言的高级特性和用法。读者可以学习到Go语言的面向对象编程、并发编程、网络编程等关键技术。并发编程是Go语言的一个独特特性,对于提高程序性能和扩展能力非常重要。 此外,该书还包含了对常见问题和陷阱的讲解,帮助读者避免一些常见的错误和陷阱。同时,书中提供了大量的案例和实践项目,读者可以通过实际操作来巩固所学内容。 《Go语言圣经》以其简洁明了的风格和对细节的深入讲解而闻名。无论是作为初学者的入门指南,还是作为有经验的开发者的参考书,这本书都能满足读者的需求。此外,该书的PDF版本能够方便地在线或离线阅读,为读者提供了更加便捷的学习体验。 综上所述,《Go语言圣经》是一本内容丰富、权威性强的优秀教材。它不仅适合Go语言的初学者,也适用于那些想要深入学习和掌握Go语言的开发者。无论是在线阅读还是PDF版本,读者都能够方便地获取和利用这本宝贵的学习资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值