使用 wget 递归获取包含任意文件的目录

Posted

技术标签:

【中文标题】使用 wget 递归获取包含任意文件的目录【英文标题】:Using wget to recursively fetch a directory with arbitrary files in it 【发布时间】:2010-09-21 09:14:57 【问题描述】:

我有一个存储一些配置文件的网络目录。我想使用 wget 来拉下这些文件并保持它们当前的结构。例如,远程目录如下所示:

http://mysite.com/configs/.vim/

.vim 包含多个文件和目录。我想使用 wget 在客户端上复制它。似乎无法找到正确的 wget 标志组合来完成这项工作。有什么想法吗?

【问题讨论】:

【参考方案1】:

您必须将-np/--no-parent 选项传递给wget(当然除了-r/--recursive),否则它将按照我网站上目录索引中的链接父目录。所以命令看起来像这样:

wget --recursive --no-parent http://example.com/configs/.vim/

为避免下载自动生成的index.html 文件,请使用-R/--reject 选项:

wget -r -np -R "index.html*" http://example.com/configs/.vim/

【讨论】:

添加 -nH(删除主机名)--cut-dirs=X(删除 X 目录)。不得不为 X 手动计算目录有点烦人.. 为什么这些对w3.org/History/1991-WWW-NeXT/Implementation 不起作用?它只会下载 robots.txt @matteo 因为 robots.txt 可能不允许抓取该网站。您应该添加 -e robots=off 以强制抓取。 如果你不想下载整个内容,你可以使用: -l1 只下载目录(你的例子是example.com) -l2 下载目录和所有一级子文件夹(' example.com/something' 但不是 'example.com/somthing/foo') 等等。如果您不插入 -l 选项,wget 将自动使用 -l 5。如果您插入 -l 0,您将下载整个 Internet,因为 wget 将跟踪它找到的每个链接。 ***.com/a/19695143/6785908 为什么我总是得到一个 index.html 文件而不是目录? wget -r --no-parent -e robots=off http://demo.inspiretheme.com/templates/headlines/images/这个命令只会得到一个index.html文件【参考方案2】:

递归下载目录,拒绝 index.html* 文件并下载没有主机名、父目录和整个目录结构:

wget -r -nH --cut-dirs=2 --no-parent --reject="index.html*" http://mysite.com/dir1/dir2/data

【讨论】:

我无法让它工作:wget -r -nH --cut-dirs=3 --no-parent --reject="index.html*" w3.org/History/1991-WWW-NeXT/Implementation --cut -dirs=2 也不起作用它只下载实际位于根文件夹中的 robots.txt。我错过了什么? @matteo 尝试添加:-e robots=off 递归获取一个目录下的所有目录,使用 wget -r -nH --reject="index.html*" mysite.io:1234/dir1/dir2【参考方案3】:

对于其他有类似问题的人。 Wget 关注robots.txt,这可能不允许您获取该站点。不用担心,您可以将其关闭:

wget -e robots=off http://www.example.com/

http://www.gnu.org/software/wget/manual/html_node/Robot-Exclusion.html

【讨论】:

当您忽略 robots.txt 时,您至少应该限制您的请求。此答案中建议的行为非常不礼貌。 @Nobody 那么礼貌的回答是什么? @PhaniRithvij 速率限制你的请求,wget 有它的参数。请注意,有些人可能仍然会提出问题,并且考虑到 robots 文件明确告诉您不允许执行您当前正在执行的操作,您甚至可能会遇到法律问题。 我在尝试此操作时遇到了一个无用的 robots.txt 文件,但在没有此选项的情况下找到了解决方法:我需要的文件也托管在 FTP 服务器上,并以镜像模式运行 wget在 FTP 服务器上工作正常。【参考方案4】:

您应该使用 -m(镜像)标志,因为它注意不要弄乱时间戳并无限期地递归。

wget -m http://example.com/configs/.vim/

如果你在这个帖子中添加其他人提到的点,那就是:

wget -m -e robots=off --no-parent http://example.com/configs/.vim/

【讨论】:

【参考方案5】:

下面是完整的 wget 命令,可用于从服务器目录下载文件(忽略 robots.txt):

wget -e robots=off --cut-dirs=3 --user-agent=Mozilla/5.0 --reject="index.html*" --no-parent --recursive --relative --level=1 --no-directories http://www.example.com/archive/example/5.3.0/

【讨论】:

这没有为我下载所有子目录【参考方案6】:

如果--no-parent 没有帮助,您可以使用--include 选项。

目录结构:

http://<host>/downloads/good
http://<host>/downloads/bad

而你要下载downloads/good而不是downloads/bad目录:

wget --include downloads/good --mirror --execute robots=off --no-host-directories --cut-dirs=1 --reject="index.html*" --continue http://<host>/downloads/good

【讨论】:

【参考方案7】:
wget -r http://mysite.com/configs/.vim/

为我工作。

也许您有一个干扰它的 .wgetrc?

【讨论】:

【参考方案8】:

要使用用户名和密码递归获取目录,请使用以下命令:

wget -r --user=(put username here) --password='(put password here)' --no-parent http://example.com/

【讨论】:

【参考方案9】:

此版本递归下载,不创建父目录。

wgetod() 
    NSLASH="$(echo "$1" | perl -pe 's|.*://[^/]+(.*?)/?$|\1|' | grep -o / | wc -l)"
    NCUT=$((NSLASH > 0 ? NSLASH-1 : 0))
    wget -r -nH --user-agent=Mozilla/5.0 --cut-dirs=$NCUT --no-parent --reject="index.html*" "$1"

用法:

    添加到~/.bashrc或粘贴到终端 wgetod "http://example.com/x/"

【讨论】:

【参考方案10】:

你只需要两个标志,一个是 "-r" 用于递归,"--no-parent"(或-np)为了不进入 '.'".." 。像这样:

wget -r --no-parent http://example.com/configs/.vim/

就是这样。它将下载到以下本地树中:./example.com/configs/.vim。 但是,如果您不想要前两个目录,请使用前面回复中建议的附加标志 --cut-dirs=2

wget -r --no-parent --cut-dirs=2 http://example.com/configs/.vim/

它只会将你的文件树下载到./.vim/

事实上,我从wget manual 得到了这个答案的第一行,他们在第 4.3 节末尾有一个非常干净的例子。

【讨论】:

【参考方案11】:

在处理递归下载时,以下选项似乎是完美的组合:

wget -nd -np -P /dest/dir --recursive http://url/dir1/dir2

为方便起见,来自手册页的相关 sn-ps:

   -nd
   --no-directories
       Do not create a hierarchy of directories when retrieving recursively.  With this option turned on, all files will get saved to the current directory, without clobbering (if a name shows up more than once, the
       filenames will get extensions .n).


   -np
   --no-parent
       Do not ever ascend to the parent directory when retrieving recursively.  This is a useful option, since it guarantees that only the files below a certain hierarchy will be downloaded.

【讨论】:

【参考方案12】:

首先,感谢所有发布答案的人。这是我递归下载网站的“终极”wget 脚本:

wget --recursive $comment# self-explanatory \
  --no-parent $comment# will not crawl links in folders above the base of the URL \
  --convert-links $comment# convert links with the domain name to relative and uncrawled to absolute \
  --random-wait --wait 3 --no-http-keep-alive $comment# do not get banned \
  --no-host-directories $comment# do not create folders with the domain name \
  --execute robots=off --user-agent=Mozilla/5.0 $comment# I AM A HUMAN!!! \
  --level=inf  --accept '*' $comment# do not limit to 5 levels or common file formats \
  --reject="index.html*" $comment# use this option if you need an exact mirror \
  --cut-dirs=0 $comment# replace 0 with the number of folders in the path, 0 for the whole domain \
$URL

之后,可能需要来自 main.css?crc=12324567 等 URL 的 stripping the query params 并运行本地服务器(例如,通过您刚刚编写的目录中的 python3 -m http.server)来运行 JS。请注意,--convert-links 选项仅在完全爬网完成后才会生效。

另外,如果您想获得一个可能很快会关闭的网站,您应该get in touch with the ArchiveTeam 并要求他们将您的网站添加到他们的 ArchiveBot 队列中。

【讨论】:

【参考方案13】:

Wget 1.18 可能会更好,例如,我被 1.12 版本的 bug 咬了...

wget --recursive (...)

...只检索 index.html 而不是所有文件。

解决方法是注意一些 301 重定向并尝试新位置 - 给定新 URL,wget 会获取目录中的所有文件。

【讨论】:

【参考方案14】:

递归 wget 忽略机器人(用于网站)

wget -e robots=off -r -np --page-requisites --convert-links 'http://example.com/folder/'

-e robots=off 导致它忽略该域的 robots.txt

-r 使其递归

-np = 没有父级,因此它不会跟随到父级文件夹的链接

【讨论】:

【参考方案15】:

听起来您正在尝试获取文件的镜像。虽然wget 有一些有趣的 FTP 和 SFTP 用途,但一个简单的镜像应该可以工作。只需几个注意事项即可确保您能够正确下载文件。

尊重robots.txt

确保如果您的public_htmlwwwconfigs 目录中有/robots.txt 文件,它不会阻止抓取。如果是这样,您需要使用 wget 命令中的以下选项通过添加来指示 wget 忽略它:

wget -e robots=off 'http://your-site.com/configs/.vim/'

将远程链接转换为本地文件。

此外,必须指示wget 将链接转换为下载的文件。如果您已正确完成上述所有操作,那么您应该没问题。我发现获取所有文件的最简单方法是使用mirror 命令,前提是在非公共目录后面没有隐藏任何内容。

试试这个:

wget -mpEk 'http://your-site.com/configs/.vim/'

# If robots.txt is present:

wget -mpEk robots=off 'http://your-site.com/configs/.vim/'

# Good practice to only deal with the highest level directory you specify (instead of downloading all of `mysite.com` you're just mirroring from `.vim`

wget -mpEk robots=off --no-parent 'http://your-site.com/configs/.vim/'

使用-m 而不是-r 是首选,因为它没有最大递归深度并且它会下载所有资产。 Mirror 非常擅长确定网站的完整深度,但是如果您有很多外部链接,您最终可能会下载的不仅仅是您的网站,这就是我们使用 -p -E -k 的原因。制作页面的所有先决条件文件和保留的目录结构应该是输出。 -k 将链接转换为本地文件。 因为你应该有一个链接设置,你应该得到你的配置文件夹,其中包含一个文件/.vim

镜像模式也适用于设置为ftp:// 的目录结构。

一般经验法则:

根据您要创建镜像的站点的哪一侧,您会向服务器发送许多调用。为了防止您被列入黑名单或被切断,请使用wait 选项来限制您的下载。

wget -mpEk --no-parent robots=off --random-wait 'http://your-site.com/configs/.vim/'

但是,如果您只是下载 ../config/.vim/ 文件,则不必担心它会忽略父目录并下载单个文件。

【讨论】:

【参考方案16】:

你应该可以通过添加 -r 来做到这一点

wget -r http://***.com/

【讨论】:

这并不是真正下载目录,而是它可以在服务器上找到的所有文件,包括您要下载的目录之上的目录。

以上是关于使用 wget 递归获取包含任意文件的目录的主要内容,如果未能解决你的问题,请参考以下文章

使用wget命令爬取整站

wget中的递归与外部目录

wget命令

获取递归包含在目录中的文件列表的最快方法是啥?

谁用过wget向服务器用post上传文件

使用wget将文件下载到目录并将电子邮件链接/附件下载到地址