1

我已经花了几个小时试图解决这个问题,而 Rebol 似乎无法做到这一点。这是一个从网页下载所有图像的程序。很高兴看到我可以用更少的代码行来编写它,但性能却很糟糕。下载 4-5 个文件后 Rebol 超时。通过添加到循环的末尾来减少超时,wait 5但这需要的时间太长了!

一个相同的程序是用 C 语言编写的,它可以立即下载所有内容。这是 Rebol 中下载图像的部分代码:

http://pastebin.com/fTnq8A3m

4

3 回答 3

2

您的脚本中有许多错误http://pastebin.com/fTnq8A3m的脚本中有许多错误

例如你有

write ... read/binary ...

所以你正在以二进制形式读取图像,然后将其写成文本。当 url 已经作为 url 存在时,您也将 url 作为文本处理!数据类型。

所以在

read/binary join http://www.rebol.com/ %image.jpg

那里的加入保留了数据类型!完好无损的。没有必要这样做

read/binary to-url join "http://www.rebol.com/" %image.jpg

这些图像的尺寸是多少?

添加等待 5 也不会影响下载,因为您正在尝试阻塞同步下载,而且由于您使用的是按钮,您将在 VID 内部,这意味着在等待中使用等待。

另一种方法是设置一个异步处理程序,然后开始下载,这样您就不会像现在那样阻塞 GUI。

于 2013-01-30T00:30:48.737 回答
2

多年来将 REBOL 用于商业应用程序,其中大多数都需要联网,从多种方式来看,我可以肯定 REBOL 的联网非常稳定。事实上,它可以让服务器运行数月而没有任何内存泄漏。

但是由于您有一个非常具体的目标,我想我会制作一个小应用程序,向您展示如何完成和工作。

这绝对适用于 R2。您可能遇到的一个问题是网络端口超时,但只有当您下载的服务器和/或图像需要几秒钟并且花费的时间超过默认的 30 秒超时时,才会出现这种情况。

下面的应用程序使用单个 url 作为其参数(您可以将其设置为靠近顶部的任何内容),它将下载其在页面上找到的所有<IMG> url。它支持 http 和 https,我已经在一些网站上进行了测试,比如 wikipedia、bing、google 图片搜索,它运行良好……每台服务器的下载率都相当稳定。我在最小 gui 上添加了速度报告,让您了解下载速率。

请注意,这是一个同步应用程序,它只是下载图像列表......你不能简单地添加一个 gui 并期望它同时运行,因为这需要一个完全不同的网络模型(异步 http 端口),这需要更复杂的网络代码。

rebol [
    title: "webpage images downloader example"
    notes: "works with R2 only"
]

; the last page-url is the one to be used... feel free to change this
page-url: http://en.wikipedia.org/wiki/Dog
page-url: https://www.google.com/search?q=dogs&tbm=isch
page-url: http://www.bing.com/images/search?q=dogs&go=&qs=ds

;------
; automatically setup URL-based information
page-dir: copy/part page-url find/last/tail page-url "/"
page-host: copy/part page-url find/tail at page-url 8 "/"

?? page-url
?? page-dir
?? page-host

output-dir: %downloaded-images/  ; save images in a subdir of current-directory
unless exists? output-dir [make-dir output-dir ]

images: []

;------
; read url (expecting an HTML document)
;
; Parse is used to collect and cleanup URLs, make them absolute URLs. 
parse/all read page-url [
    some [
        thru {<img } thru {src="} copy image to {"} (
            case [
                "https://" = copy/part image 8 [image: to-url image]
                "http://" = copy/part image 7 [image: to-url image]
                "//" = copy/part image 2 [image: join  http:// at image 3  ]
                #"/" = pick image 1 [image: join page-host image ]
                'default [image: join page-dir image]
            ]
            append images image
         )
    ]
]

;------
; pretty-print image list
new-line/all images yes
probe images

;------
; display report window
view/new layout [ field-info: text 500 para [wrap?: false]   speed-info: text 500    ]

;------
; download images and report all activity
i: bytes: 0
s: now/precise
foreach image images [
    unless attempt [
        i: i + 1 
        probe image
        legal-chars: charset [#"a" - #"z" #"A" - #"Z" "0123456789-_.="] 
        fname: to-string find/last/tail image "/" ; get filename from url

        parse/all fname [some [ legal-chars | letter: skip  (change letter "-") ] ] ; convert illegal filename chars

        fname: join output-dir to-file fname ; use url filename to build disk path
        write/binary fname read/binary image ; download file

        ; update GUI
        t: difference now/precise s

        field-info/text: rejoin ["Downloading: (" i "/" length? images ") "  fname]
        show field-info

        bytes: bytes + size? fname
        speed-info/text: rejoin ["bytes: "  bytes ",   time: "  t   ",   speed : " (bytes / 1000) / ( to-decimal t) "kb/s"]
        show speed-info

        true ; all is good, attempt should return a value
    ][
        print "^/^/---^/unable to download image:"
        print image
        print "---^/^/"
    ]
]

如果您不需要网页扫描仪并且有要抓取的手动图像列表,只需将该代码替换为如下所示的图像块:

images: [ 
    http://server.com/img1.png
    http://server.com/img2.png
    http://server.com/img3.png
]

让下载循环完成它的工作。

希望这可以帮助

于 2013-01-30T06:48:30.370 回答
1

需要漫长的等待吗?在长循环中,rebol 需要不时等待来处理 gui 事件,但 IIRC 等待 0 应该可以解决问题。事件排队是否有可能产生问题?

于 2013-01-31T04:07:32.747 回答