• R语言
  • download.file() 无法下载网络图片

从网页上批量下载和整理图片,书中代码如下:
也复制了该链接到浏览器里面试了,浏览器能正常进去,但是文件却显示为空,不知道是什么原因?

> urlink <- 'http://www.biomet.co.at/pictures/'
> aa <- readLines(urlink, encoding = 'UTF-8')
Warning message:
In readLines(urlink, encoding = "UTF-8") :
  incomplete final line found on 'http://www.biomet.co.at/pictures/'
> 
> linkformat <- 'src = "http://www.biomet.co.at/wp/wp-content/gallery'
> bb <- aa[grep(linkformat, aa)]
> 
> for(i in 1:length(bb))
+   bb[i] <- substring(
+     bb[i],
+     regexpr("http", bb[i])[1],
+     regexpr(".jpg\"", bb[i])[1] + 3)
>  
> bb <- unique(bb)
> bb
[1] NA
> length(bb)
[1] 1
> writeLines(bb, 'c:/r4r/links.txt')
> 
> stname <- substring(bb, 47, 50)
> stname <- stname[-which(stname == '')]
> for(i in unique(stname))
+   dir.create(paste('c:/r4r', i, sep = ''))
> 
> for(i in 1:length(bb)) {
+   download.file(url = bb[i],
+                 destfile = paste('c:/r4r/', stname[i], '/',
+                                  stname[i], i, '.jpg', sep = " "),
+                 method = 'curl', quiet = T)
+   print(paste(i, 'of', length(bb), 'downloaded.'))
+ }
Error in download.file(url = bb[i], destfile = paste("c:/r4r/", stname[i],  : 
  'curl' call had nonzero exit status

以上为所有代码,有朋友碰到过这样的问题麽,烦请赐教!不胜感激!

    junfei 这里包含了两个问题。

    第一,'文件却显示为空'。

    这是因为代码的第二行并未生效,并未把网页读进来。原因如 @tctcab 所言,可能是因为你用的是 windows 操作系统,而你的操作系统里没有安装 curl。所以,单单是为了这一行生效的话,需要改成:

    aa <- readLines(url(urlink), encoding = 'UTF-8')

    第二,'curl' call had nonzero exit status

    这是因为,当运行到 download.file时,由于你没有装 curl,所以 method = 'curl'无法生效。你可以把 method = 'curl' 去掉,这样,图片虽然可以下载,但是打开时会有问题。我不知道这是 windows 的问题还是图片浏览软件的问题,没有深究。我试过了method 取其他值,得到的图片都没法在 windows 下正常浏览。

    要解决这个问题,需要安装 curl。如果安装了 curl,那么书里的代码(包括第一个问题)不需要更改,可以正常运行。

    抱歉,写书的时候没有注意到这一点,想来是当时我的电脑里已经装好了 curl。

      dapengde 我已经下载了Windows 64 bit的curl-7.64.1-win64-binary the curl project,运行了其中的curl.exe应用程序,出现了一个程序窗口但是一闪而过,似乎并没有安装成功,运行上述代码,报错依旧存在!不知所以!

        junfei 你用不着手动运行 curl.exe。它又不是个安装包。

        可能你需要把它的路径添加到环境变量里。

          dapengde 感觉也不是有没有curl的问题!我直接复制了这两个链接到浏览器中,第一个链接能打开,第二个链接不能。我删除了下载的curl,R中也有curl这个功能,同样显示的是第一个链接能打开,第二个链接不能。代码如下:

          > curl::curl("http://www.biomet.co.at/pictures/", open = "r")
          A connection with                                               
          description "http://www.biomet.co.at/pictures/"
          class       "curl"                             
          mode        "r"                                
          text        "text"                             
          opened      "opened"                           
          can read    "yes"                              
          can write   "no"                               
          > curl::curl("http://www.biomet.co.at/wp/wp-content/gallery", open = "r")
          Error in open.connection(con, open = mode) : HTTP error 403.

          估计是因为服务器的原因,第二个链接在我这打不开,所以才有之前的两个问题。

            junfei 第二个链接我也打不开。你的 curl 路径加到环境变量里了吗?

              > bd <- '1994-9-22 20:30:00'
              > bdtime <- strptime(x = bd,  format = '%Y-%m-%d %H:%M:%S',  tz = "Asia/shanghai")
              > unlist(unclass(bdtime))
                 sec min hour mday mon year wday yday isdst zone gmtoff 
                 "0" "30" "20" "22" "8" "94" "4" "264" "0" "CST" NA 

              这是提取时间的年月日时分秒代码,但是我发现其中有个问题就是,提取的月份总是比实际月份少了一个月,不知道这是不是软件bug,还是另有说法呢?
              奇怪奇怪,少见则多怪!

                dapengde 请问一下环境变量是指单独加一行curl <- “本地的路径”,还是怎麽的呢?
                curl <- "d:/CURL/curl-7.64.1-win64-mingw/bin/curl.exe"
                加了这行代码上去了,但是后面的warning与error还是一样的。

                  junfei

                  事实上看了一下download.file的帮助,window的method改成"wininet"应该就行了

                  不过我测了一下,这样下载下来的文件会报错,换成curl::curl_download()就行,你可以试试装一下curl这个包
                  install.packages("curl")

                  代码

                  urlink <- 'http://www.biomet.co.at/pictures/'
                  aa <- readLines(urlink, encoding = 'UTF-8')
                  linkformat <- '/wp-content/gallery/.*jpg.*'
                  bb <- aa[grep(linkformat, aa)]
                  
                  bb.jpgs = gsub(".*(http.*?.jpg).*","\\1", head(bb))
                  
                  dir.create("c:/r4r")
                  
                  lapply(bb.jpgs, function(fn){
                    curl::curl_download(fn, destfile = paste0("c:/r4r/",basename(fn)))
                  })

                  junfei
                  时间的话

                  在help("DateTimeClasses")里写的是

                  mon
                  0–11: months after the first of the year.

                  如果要提取时间,建议使用lubridate包,

                  比如

                  lubridate::month(strptime("1994-9-22", format = "%Y-%m-%d"))
                  #> [1] 9

                  <sup>Created on 2019-03-31 by the reprex package (v0.2.1)</sup>

                    junfei 在我这里测试,只要把 curl 的路径加到系统的环境变量里,就迎刃而解了。照tctcab 给的链接做就行。

                    tctcab 我觉得不算复杂,作为 R 语言的 Windows 用户,还是应该了解一下为好,说不定就被逼进了 linux 阵营。

                    method 上面我说了,用别的值在windows下载的图片打不开。

                      junfei 不相关的问题最好新开一帖。月份是从 0 算起的。不知道为什么。

                      tctcab 我是能不用额外包就不用。
                      format(strptime("1994-9-22", format = "%Y-%m-%d"), format = "%m") 就够了吧。

                      dapengde 已把curl路径加到了系统的环境变量中D:\CRUL\curl-7.64.1-win64-mingw\bin\curl.exe,然后试运行了代码,发现还是老样子报错!这个问题还竟无可奈何呀!

                        junfei

                        按我上面的代码装curl包试试,应该会自动帮你弄好curl路径什么的

                          junfei

                          要添加的路径应该是 D:\CRUL\curl-7.64.1-win64-mingw\bin\,不是 D:\CRUL\curl-7.64.1-win64-mingw\bin\curl.exe。

                          添加完之后在 cmd 里运行一下 curl。如果能运行,说明添加成功了。

                            tctcab 摁摁,安装了curl包后可以正常下载图片了,谢谢您啦!时间提取包我会去尝试的,谢谢前辈您的指点啦!
                            dapengde 也非常谢谢赵老师的悉心指点!对于默认的月份都是从0开始的话那也就不足为奇了,只是对初学的我来说确实也是疑惑了些!现在明了,谢谢您!

                            dapengde
                            摁,按您指点改了路径之后在cmd中运行了...\bin\curl.exe,显示出如下一行代码:
                            curl:try ‘curl--help’ or 'curl--manual' for more information
                            然后在Rstudio中运行之前代码,报错依旧不肯罢休呢!

                            > bb
                            [1] NA
                            > length(bb)
                            [1] 1