我已经花了几个小时试图解决这个问题,而 Rebol 似乎无法做到这一点。这是一个从网页下载所有图像的程序。很高兴看到我可以用更少的代码行来编写它,但性能却很糟糕。下载 4-5 个文件后 Rebol 超时。通过添加到循环的末尾来减少超时,wait 5
但这需要的时间太长了!
一个相同的程序是用 C 语言编写的,它可以立即下载所有内容。这是 Rebol 中下载图像的部分代码:
我已经花了几个小时试图解决这个问题,而 Rebol 似乎无法做到这一点。这是一个从网页下载所有图像的程序。很高兴看到我可以用更少的代码行来编写它,但性能却很糟糕。下载 4-5 个文件后 Rebol 超时。通过添加到循环的末尾来减少超时,wait 5
但这需要的时间太长了!
一个相同的程序是用 C 语言编写的,它可以立即下载所有内容。这是 Rebol 中下载图像的部分代码:
您的脚本中有许多错误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。
多年来将 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
]
让下载循环完成它的工作。
希望这可以帮助
需要漫长的等待吗?在长循环中,rebol 需要不时等待来处理 gui 事件,但 IIRC 等待 0 应该可以解决问题。事件排队是否有可能产生问题?