R语言批量抓取网页ZIP文件报错求助:零长度输入混合问题
解决R中mapply下载zip文件时的"zero-length inputs"错误
这个错误的核心问题很明确:你的urls和files两个向量要么长度不匹配,要么其中一个是空的,导致mapply无法正常执行。咱们一步步排查和解决:
1. 先修正正则表达式的问题
你用的grep("*.zip", ...)是错误的正则写法——在正则语法里,*是用来修饰前面字符的(表示零次或多次匹配),而你这里*前面没有任何字符,根本匹配不到任何.zip文件,这大概率是导致files为空向量的原因。
把正则改成匹配以.zip结尾的链接,更准确:
files <- grep("\\.zip$", sapply(nodes_a, function(node) xmlGetAttr(node, "href")), value = TRUE)
解释:\\.是转义的点号(因为.在正则里默认匹配任意字符),$表示字符串结尾,这样只会抓到真正的zip文件链接,避免误匹配类似.zip.txt这类无关链接。
2. 验证你的向量是否有效
在执行下载前,先打印files和urls的长度和内容,确认它们非空且长度一致:
cat("找到的zip文件数量:", length(files), "\n") print(files) cat("拼接后的下载链接数量:", length(urls), "\n") print(urls)
如果输出显示数量为0,那说明你的xpath没抓到正确的<a>标签,或者网页上根本没有zip链接。这时候可以换更精准的xpath直接筛选带zip的链接,省去后续grep的步骤:
# 直接筛选href包含.zip的a标签 nodes_a <- getNodeSet(zipped, "//a[contains(@href, '.zip')]") files <- sapply(nodes_a, function(node) xmlGetAttr(node, "href"))
3. 修复下载代码的细节
即使向量没问题,下载zip这类二进制文件时,最好加上mode = "wb"参数,避免在Windows系统下出现文件损坏的情况。另外,先做个判断,确保向量非空再执行下载:
if (length(urls) > 0 && length(urls) == length(files)) { mapply(function(x, y) download.file(x, y, mode = "wb"), urls, files) } else { warning("没有找到可下载的zip文件,或者urls与files长度不匹配!") }
完整修正后的代码示例
library(XML) url <- "http://blablabla" # 单个url不需要用c()包裹 zipped <- htmlParse(url) # 方法1:用xpath直接筛选zip链接(更高效) nodes_a <- getNodeSet(zipped, "//a[contains(@href, '.zip')]") files <- sapply(nodes_a, function(node) xmlGetAttr(node, "href")) # 方法2:先抓所有a标签再用正则筛选(适合需要复杂匹配规则的场景) # nodes_a <- getNodeSet(zipped, "//a") # files <- grep("\\.zip$", sapply(nodes_a, function(node) xmlGetAttr(node, "href")), value = TRUE) # 拼接完整下载链接 urls <- paste(url, files, sep = "") # 验证并执行下载 if (length(urls) > 0 && length(urls) == length(files)) { mapply(function(x, y) download.file(x, y, mode = "wb"), urls, files) cat("所有文件下载完成!") } else { warning("未找到有效zip文件链接,请检查网页结构或xpath表达式!") }
内容的提问来源于stack exchange,提问作者Helena
相关产品推荐
相关产品推荐

