[日常] Go语言圣经--并发的web爬虫
两种:
crawler.go
package main import (
"fmt"
"links"
//"log"
"os"
) func main() {
worklist := make(chan []string) // Start with the command-line arguments.
go func() { worklist <- os.Args[1:] }()
// Crawl the web concurrently.
seen := make(map[string]bool)
for list := range worklist {
for _, link := range list {
if !seen[link] {
seen[link] = true
go func(link string) {
worklist <- crawl(link)
}(link)
}
}
}
} var tokens = make(chan struct{}, 20) //从一个url页面中提取出所有的url
func crawl(url string) []string {
fmt.Println(url)
tokens <- struct{}{}
list, err := links.Extract(url)
<-tokens
if err != nil {
//log.Print(err)
}
return list
}
crawler2.go
package main import (
"fmt"
"links"
//"log"
"os"
"strings"
) func main() {
worklist := make(chan []string)
unseenLinks := make(chan string) // Start with the command-line arguments.
go func() { worklist <- os.Args[1:] }()
// Create 20 crawler goroutines to fetch each unseen link.
for i := 0; i < 20; i++ {
go func() {
for link := range unseenLinks {
//if strings.HasPrefix(link, "http://www.lypeng.com") {
foundLinks := crawl(link)
go func() { worklist <- foundLinks }() //}
}
}()
} // The main goroutine de-duplicates worklist items
// and sends the unseen ones to the crawlers.
seen := make(map[string]bool)
for list := range worklist {
for _, link := range list {
if !seen[link] {
seen[link] = true
unseenLinks <- link
}
}
}
} //从一个url页面中提取出所有的url
func crawl(url string) []string {
fmt.Println(url)
list, err := links.Extract(url)
if err != nil {
//log.Print(err)
}
return list
}
[日常] Go语言圣经--并发的web爬虫的更多相关文章
- [日常] GO语言圣经-并发获取多个URL
go语言圣经-并发获取多个URL 1.GO最新奇的特性就是对并发编程的支持,goroutine和channel 2.goroutine是一种函数的并发执行方式,而channel是用来在goroutin ...
- [日常] Go语言圣经-并发的非阻塞缓存
1.go test命令是一个按照约定和组织进行测试的程序2.竞争检查器 go run -race 附带一个运行期对共享变量访问工具的test,出现WARNING: DATA RACE 说明有数据竞争3 ...
- [日常] Go语言圣经--并发的循环习题
练习 8.4: 修改reverb2服务器,在每一个连接中使用sync.WaitGroup来计数活跃的echo goroutine.当计数减为零时,关闭TCP连接的写入,像练习8.3中一样.验证一下你的 ...
- [日常] Go语言圣经-WEB服务与习题
Go语言圣经-web服务 1.Web服务程序,标准库里的方法已经帮我们完成了大量工作 2.main函数将所有发送到/路径下的请求和handler函数关联起来,/开头的请求其实就是所有发送到当前站点上的 ...
- [日常] Go语言圣经-文本和HTML模板习题
Go语言圣经-文本和HTML模板 练习 4.14: 创建一个web服务器,查询一次GitHub,然后生成BUG报告.里程碑和对应的用户信息. 1.查看下文档godoc net/http |grep H ...
- [日常] Go语言圣经--结构体,JSON习题
Go语言圣经-结构体 1.结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体 2.通常一行对应一个结构体成员,成员的名字在前类型在后,不过如果相邻的成员类型如果相同的话可以被合并到一行 ...
- [日常] Go语言圣经前言
https://books.studygolang.com/gopl-zh/ go语言圣经 1.Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”. 2.Go语言中和并发编程相关的特性是 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-Panic异常,Recover捕获异常习题
Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...
随机推荐
- 使用c# 实现冒泡排序
冒泡排序是一个经典的案例 实现原理就数与数前后两两比较,如果前面比后面大则交换位置.最终达到从小到大的顺序,这样的排序方式就是冒泡排序. //冒泡排序 ;//定义一个中间变量,用来交换值 , , , ...
- C#实时检测端口占用情况
在TCP/IP协议中,服务端需要去监听客户端的端口,开始监听,我们需要检测使用的端口是否被占用,获取系统当前使用的所有端口号,用此端口进行匹配即可. 代码如下 internal static Bool ...
- 前端基础-html 字体标签,排版标签,超链接,图片标签
主要内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...
- Dubbo实现原理之基于SPI思想实现Dubbo内核
dubbo中SPI接口的定义如下: @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public ...
- [Swift]优先队列PriorityQueue(自定义数据结构)
优先队列[priority queue] 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除. 优先队列特点:在优先队列中,元素被赋予优先级. 当访问元素时,具有最高优先级的元素最先 ...
- 在MySQL Workbench查看表,表结构,索引,函数,存储过程,触发器,重连
表 表结构 索引 触发器 存储过程 函数 重新连接 出现Error Code: 2006 MySQL server has gone away时
- 【sping揭秘】11、Java 平台上的AOP实现机制
动态代理 Jdk1.3只有引入的动态代理机制,可以再运行期间,为相应的接口(必须得有接口)动态生成对应的代理对象 基于以上问题,我们可以将横切关注点逻辑封装到动态代理的invocationhandle ...
- javascript数据结构与算法---二叉树(查找最小值、最大值、给定值)
javascript数据结构与算法---二叉树(查找最小值.最大值.给定值) function Node(data,left,right) { this.data = data; this.left ...
- odoo开发笔记-自定义发送邮件模板
1. 首先激活开发者模式 2. 点击设置 - Email - 模板 - “选择你需要修改的模板” 我们以销售模块-报价单 邮件模板为例 来说明. quote order 原先默认模板,发出的邮件显示效 ...
- Scala之隐式转换implicit详解
假设我们有一个表示文本的行数的类LineNumber: class LineNumber ( val num : Int ) 我们可以用这个类来表示一本书中每一页的行数: val lineNumOfP ...