练习:网络爬虫 - 并发不起作用

2024-04-21

我正在经历 golang 之旅,并致力于最后的练习,以将网络爬虫更改为并行爬行而不是重复爬行(http://tour.golang.org/#73 http://tour.golang.org/#73)。我所改变的只是抓取功能。

    var used = make(map[string]bool)

    func Crawl(url string, depth int, fetcher Fetcher) {
        if depth <= 0 {
            return
        }
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("\nfound: %s %q\n\n", url, body)
        for _,u := range urls {
            if used[u] == false {
                used[u] = true
                Crawl(u, depth-1, fetcher)
            }
        }
        return
    }

为了使其并发,我在调用函数 Crawl 之前添加了 go 命令,但程序不是递归调用 Crawl 函数,而是只找到“http://golang.org/ http://golang.org/“页面,没有其他页面。

为什么当我在函数Crawl的调用中添加go命令时,程序无法运行?


问题似乎是,您的进程在所有 URL 都可以被跟踪之前就退出了 通过爬虫。由于并发的原因,main()程序在之前退出 工人们已经完成了。

为了规避这个问题,你可以使用sync.WaitGroup http://golang.org/pkg/sync/#WaitGroup:

func Crawl(url string, depth int, fetcher Fetcher, wg *sync.WaitGroup) {
    defer wg.Done()
    if depth <= 0 {
         return
    }
    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("\nfound: %s %q\n\n", url, body)
    for _,u := range urls {
        if used[u] == false {
           used[u] = true
           wg.Add(1)
           go Crawl(u, depth-1, fetcher, wg)
        }
    }
    return
}

并打电话Crawl in main如下:

func main() {
    wg := &sync.WaitGroup{}

    Crawl("http://golang.org/", 4, fetcher, wg)

    wg.Wait()
}

Also, 不要依赖线程安全的地图 http://golang.org/doc/go_faq.html#atomic_maps.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

练习:网络爬虫 - 并发不起作用 的相关文章

  • 如何使用json传递opentracing数据

    我的 API 网关启动一个跟踪器和一个用于验证电子邮件的范围 然后它传递给user service用于验证 我想通过这个span详情至user service作为 json 对象并启动另一个span as a tracer start sp
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事
  • 在 Alpine 中找不到运行时/cgo

    In an alpine edge我安装的容器通过 RUN apk add no cache musl dev go 我试着跑go get github com golang protobuf protoc gen go then 这会导致
  • Ajax 将文件上传到内容类型为 Multipart 的 GoLang 服务器

    我正在尝试使用多部分表单将音频文件上传到 Golang 服务器 然而 Go 返回错误 multipart NextPart bufio buffer full 我相信这表明我的 Javascript 请求中存在不属于多部分格式的内容 这是我
  • 在 Go 中使用互斥锁

    我想了解互斥体是如何工作的 据我目前的理解 它是为了进行原子操作并同步对某些数据的访问 我在这里构建了一个队列数据结构的示例 https github com arnauddri algorithms blob master data st
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 如何在 Visual Studio Code 中使用 Delve 调试器进行远程调试

    我已经问过了 得到了很好的答复answer https stackoverflow com questions 39058823 how to use delve debugger in visual studio code用于使用 del
  • Go中如何从json字符串中获取键值

    我想尝试从 Go 中的 JSON 获取键值 但我不确定如何操作 我已经能够使用 simplejson 读取 json 值 但是我无法找到如何获取键值 有人能指出我正确的方向和 或帮助我吗 谢谢你 您可以通过执行以下操作来获取 JSON 结构
  • 我是否需要关心异步 Javascript 的竞争条件?

    假设我加载了一些我知道在将来某个时候会调用的 Flash 影片window flashReady并将设置window flashReadyTriggered true 现在我有一个代码块 我想在闪存准备好时执行它 我希望它立即执行 如果wi
  • 构建链代码时 ltdl.h 未找到错误

    我正在尝试使用构建链码go build 当我运行 Go build 命令时它的报告 hyperledger fabric vendor github com miekg pkcs11 pkcs11 g o 29 18 fatal error
  • 在运行的 Swing 应用程序中替换 AWT EventQueue 的安全方法

    我维护的 Swing 应用程序中的各种零星问题似乎是由它使用自己的自定义版本替换默认 AWT 事件队列的方式引起的Toolkit getDefaultToolkit getSystemEventQueue push new AEventQu
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • 如何解析 Content-Disposition 标头以检索文件名属性?

    使用 go 如何解析从 http HEAD 请求检索到的 Content Disposition 标头以获取文件的文件名 此外 如何从 http HEAD 响应中检索标头本身 这样的事情正确吗 resp err http Head http
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • 如何在 Go 中解组具有多个项目的简单 xml?

    我想从以下 xml 中获取人物 People 的一部分
  • Java 8:并行 FOR 循环

    我听说 Java 8 提供了很多关于并发计算的实用程序 因此我想知道并行给定 for 循环的最简单方法是什么 public static void main String args Set
  • Golang GAE - 小胡子结构中的 intID

    这是一个Example https www dropbox com sh ur2ws1jnik6euef PjVJSwDTUc Blog Golang zip该应用程序的 关键代码在 golang code handler handler
  • 模板中的 bson.ObjectId

    我有一个具有 bson ObjectId 类型的结构 例如如下所示 type Test struct Id bson ObjectId Name string Foo string 我想在 html 模板中呈现它 Name Food a h
  • 如何在 Go 中将环境变量传递给测试用例

    在为 Go 编写测试用例时 传递需要提供给测试的环境变量的标准方法是什么 例如 我们不想在测试用例的源代码中嵌入密码 处理这个问题最标准的方法是什么 我们让测试用例寻找配置文件吗 还有别的事吗 看来我偶然发现了答案 将其添加到测试用例中可以
  • 在 Go 中初始化嵌入结构

    我有以下内容struct其中包含一个net http Request type MyRequest struct http Request PathParams map string string 现在我想初始化匿名内部结构http Req

随机推荐

  • C++ 模板继承问题与基类型

    我有以下代码 但无法编译 template lt typename T gt class Base public typedef T TPtr void func template lt typename T gt class Derive
  • Nexus 工件删除命令

    我已使用以下命令从命令行将工件上传到 Sonatype Nexus MAVEN maven bin mvn X e 部署 部署文件 Durl http maven nexus com nexus content repositories x
  • 将公钥添加到 ~/.ssh/authorized_keys 不会自动登录

    我将公共 SSH 密钥添加到授权密钥 file ssh localhost应该让我登录而不询问密码 我这样做并尝试输入ssh localhost 但它仍然要求我输入密码 我还需要进行其他设置才能使其正常工作吗 我已按照更改权限的说明进行操作
  • MASM32 中令人困惑的括号

    我正在尝试掌握 MASM32 但对以下内容感到困惑 我认为括号用于间接 所以如果我有预定义的变量 data item dd 42 then mov ebx item 会将 item 的内容 即数字 42 放入 ebx 中并 mov ebx
  • 来自卸载事件的同步 AJAX 发布:如何确保用户在下一页加载时看到来自数据库的最新信息

    当用户请求编辑 CMS 中的条目时 我们会 锁定 它 以便其他人无法同时编辑它 当他们提交更改时 我们会释放锁定 然而 我们需要处理用户通过其他链接离开页面的情况 我的第一次尝试是使用 jQuery 来触发同步 ajax 呼吁 window
  • 通过Entity类名动态获取一个DbSet

    我正在尝试使用System Reflections得到一个DbSet
  • 如何使用批处理全屏打开窗口

    我之前用代码制作了一个批处理文件 start chrome exe profile directory Profile 1 http drive google com 它会以配置文件 1 用户的身份打开 google chrome 页面 D
  • 尝试从故事板初始化视图控制器

    我有一个视图控制器放置在主故事板中 但是当我尝试初始化并加载视图控制器时 我的应用程序崩溃了 我使用的 xcode 版本并没有真正告诉我我正确得到的错误 但我确实看到它给了我一个 sigabrt 信号 我不知道为什么它不起作用 UIStor
  • 使用文档片段真的能提高性能吗?

    我对 JS 的性能有疑问 比如说 我有下一个代码 var divContainer document createElement div divContainer id container var divHeader document cr
  • Elastic Beanstalk:Amazon Linux 2 平台上的日志任务自定义

    我想知道该怎么做日志任务定制 https docs aws amazon com elasticbeanstalk latest dg using features logging html health logs extend在新的 El
  • 如何查看定位服务是否开启?

    如何检查用户是否关闭了定位服务 这样我就可以提示他 她打开它才能使用我的应用程序 谢谢 The CLLocationManager提供类方法来确定位置服务的可用性 BOOL locationServicesEnabled for lt iO
  • 在 Visual Studio 中进行嵌入式代码开发(尤其是使用 C18 的 PIC)

    我使用 Visual Studio 编写桌面应用程序 我发现它非常用户友好且易于使用 如果可能的话 我还想在Visual Studio中编写嵌入式代码 例如 是否可以使用 C18 或任何其他类似的基于 C 的语言为 PIC18Fxxx 系列
  • javax.management.InstanceAlreadyExistsException:com.zaxxer.hikari:名称= dataSource,类型= HikariDataSource

    我怎么解决这个问题 哪个是最好的选择以及如何做到这一点 设置唯一的池名称 销毁之前的连接池 org apache catalina core ApplicationContext log Initializing Spring embedd
  • 检测unicode字符串中的非ascii字符[重复]

    这个问题在这里已经有答案了 给定一个文本文件 或 unicode 字符串 检测 ASCII 编码之外的字符的好方法是什么 我可以轻松地将每个字符迭代传递给ord 但我想知道是否有更有效 更优雅或更惯用的方法来做到这一点 这里的最终目标是编译
  • Ruby/Rails 中的夏令时开始和结束日期

    我正在开发一个 Rails 应用程序 我需要在给定特定偏移量或时区的情况下查找夏令时开始和结束日期 我基本上将从用户浏览器接收到的时区偏移保存在数据库中 3 5 并且我想在由于夏令时而改变时对其进行修改 I know Time实例变量有ds
  • 获取 OS X 中用户库文件夹的路径

    我需要打开一个 NSSavePanel 并将用户库文件夹作为目标文件夹 通常我会通过输入来做到这一点 Library in NSSavePanel beginSheetForDirectory 只要应用程序没有被沙箱化 这种方法就可以正常工
  • Android Studio 1.0.2 m2respository gradle问题

    使用Android Studio 1 0 2 并且强制使用Gradle 2 2 1 所有系统变量都是正确的 在新的更新中 旧版本的 gradle 和 m2repository 存在问题 我正在尝试导入 kickflip io android
  • 如何手动调用(查找)ReCaptcha Callback函数?

    我目前正在尝试验证码解决 并决定使用流行的 2captcha 服务来实现此目的 他们的方法是向他们发送验证码值 谷歌验证码密钥和站点线程 然后他们解决它并向我发回应该发送给谷歌的完成值 以检查验证码是否已解决 我被困在最后一步 使用返回的解
  • 包装 API 以支持依赖注入

    我正在与一个只有静态函数的 API 进行交互 并且无法打开和更改 public class WindowsNativeGraphAPI public static IEnumerable
  • 练习:网络爬虫 - 并发不起作用

    我正在经历 golang 之旅 并致力于最后的练习 以将网络爬虫更改为并行爬行而不是重复爬行 http tour golang org 73 http tour golang org 73 我所改变的只是抓取功能 var used make