[日常] 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)...)
}
}
}
}
[日常] Go语言圣经-匿名函数习题2的更多相关文章
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
- [日常] Go语言圣经-错误,函数值习题
Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-Deferred函数
1.只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法.当defer语句被执行时,跟在defer后面的函数会被延迟执行.直到包含该defer语句的函数执行完毕时,defe ...
- [日常] Go语言圣经-竞争条件习题
package main import( "fmt" "sync" ) var balance int func Deposit(amount int) { b ...
- [日常] Go语言圣经-可变参数习题
1.参数数量可变的函数称为为可变参数函数,例子就是fmt.Printf和类似函数2.参数列表的最后一个参数类型之前加上省略符号“...”3.虽然在可变参数函数内部,...int 型参数的行为看起来很像 ...
- [日常] Go语言圣经-Slice切片习题
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型:slice的语法和数组很像,只是没有固定长度而已,slice的底 ...
- [日常] Go语言圣经--接口约定习题2
练习 7.3: 为在gopl.io/ch4/treesort (§4.4)的*tree类型实现一个String方法去展示tree类型的值序列. package main import( "f ...
- [日常] Go语言圣经-函数多返回值习题
Go语言圣经-函数多返回值1.在Go中,一个函数可以返回多个值2.许多标准库中的函数返回2个值,一个是期望得到的返回值,另一个是函数出错时的错误信息3.如果一个函数将所有的返回值都显示的变量名,那么该 ...
随机推荐
- cad.net之ACAD和GCAD环境变量获取
#if AC2006 || AC2007 || AC2008 || AC2009 || AC2010 || AC2011 || AC2012 [System.Security.SuppressUnma ...
- intellij 引入本地库并war打包
一.引入本地库 1.File -> Project Structure -> Libraries,点击+,新增本地lib库. 2.File -> Project Structure ...
- 为什么transform对行内元素不生效
注:赶时间的同学可直接下拉到底,看结论. 我使用transform对一个元素进行位移,代码如下: <div class="box"> <span>今天你吃了 ...
- JPA-style positional param was not an integral ordinal
参数错误 多为SQL语句问题 例如SQL拼装中的空格,换行时首位应多加空格保持语句效果
- vue项目警告There are multiple modules with names that only differ in casing
执行npm run dev后出现了警告提示: warning in ./src/components/Public/yearSelectCell.vue There are multiple modu ...
- python3.6使用f-string来格式化字符串
这里的f-string指的是以f或F修饰的字符串,在字符串中使用{}来替换变量,表达式和支持各种格式的输出.详细的格式化定义可以看官方文档 >>> a, b = 30, 20 > ...
- 线程&线程控制
线程基本概念: 1 线程 (1)概念:linux下没有真正的线程,所谓的线程都是通过进程的pcb模拟的,因此linux下的线程也称为“轻量级进程”,之前我们所说的进程现在看来,可以理解为:只有一个线程 ...
- WebDriver高级应用实例(2)
2.1在日期选择器上进行日期选择 被测网页的网址: https://www.html5tricks.com/demo/Kalendae/index.html Java语言版本的API实例代码 impo ...
- Vue2.5开发去哪儿网App 首页开发
主页划 5 个组件,即 header icon swiper recommend weekend 一. header区域开发 1. 安装 stylus npm install stylus --s ...
- scala中的一些特殊符号的意义
1.作为“通配符”,类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就 ...