1

我需要在 Linux 上下载超过 30k 的页面,并想象我可以用一个简单的 bash 脚本 + wget 来做到这一点,这就是我想出的:

#!/bin/bash

start_time=$(date +%s)
for i in {1..30802}
do
        echo "Downloading page http://www.domain.com/page:$i"
        wget "http://www.domain.com/page:$i" -q -o /dev/null -b -O pages/$i
        running=$(ps -ef | grep wget | wc -l)
        while [ $running -gt 1000 ]
        do
                running=$(ps -ef | grep wget | wc -l)
                echo "Current running $running process."
                sleep 1;
        done
done

while [ $running -gt 1 ]
do
        running=$(ps -ef | grep wget | wc -l)
        echo "Waiting for all the process to end..."
        sleep 10;
done

finish_time=$(date +%s)
echo "Time duration: $((finish_time - start_time)) secs."

有些页面没有完全下载!

  • 由于上面的代码将使 1k wget 并行运行进程并等到它降低以添加更多进程,难道是我实际上用尽了所有可用的互联网链接?

  • 我怎样才能使它更可靠,以确保页面实际上被正确下载?

编辑:

  • 我听说 curl 是下载页面的更好选择,这是真的吗?
4

2 回答 2

2

以下是针对您的情况的可能解决方案:

1)改变你打电话wget给这样的方式:

(wget "http://www.domain.com/page:$i" -q -o /dev/null -O pages/$i || touch $i.bad) &

2) 脚本完成后,搜索所有*.bad文件并wget为每个文件重新启动。在新的重试之前删除相应的.bad文件。

3) 直到没有*.bad文件存在为止。

这是一般的想法。希望有帮助!

编辑:

对于wget进程消失、被杀死或突然结束的情况,有一个可能的细化:

(wget "http://www.domain.com/page:$i" -q -o /dev/null -O pages/$i || touch $i.bad && touch $i.ok) &

然后您可以分析某些页面是否已完全下载或wget未能结束。

编辑2:

经过一些测试和挖掘,我发现我之前的建议是有缺陷的。条件句的顺序必须互换

(wget "http://www.domain.com/page:$i" -q -o /dev/null -O pages/$i && touch $i.ok || touch $i.bad) &

所以,

  • 如果下载正确执行wget(即它以 OK 返回码完成),则必须有两个文件:下载的页面和.ok文件。

  • 如果下载失败(即wget返回一个 KO 返回码),那么肯定有.bad文件,并且可能是页面的部分下载。

无论如何,只有.ok文件是重要的:他们说下载已正确完成(从这个wget角度来看,我将在稍后讨论)。

如果没有.ok找到特定页面的文件,那么肯定没有下载,所以必须重试。

然后,我们进入您的过程中最微妙的部分:如果 Web 服务器作为对大量请求的响应,取消了那些他无法通过 HTTP 200 响应和零内容长度服务的请求,会发生什么?这将是避免网络复制或某种服务器攻击的好方法。

如果是这种情况,您必须查看响应的模式。会有一个.ok文件,但下载页面的文件大小可能为零。

您可以使用以下方法检测那些零长度下载

filesize=$(cat $i.html | wc -c)

.ok然后在和.bad文件的前一个过程中添加一些逻辑:

retry=0
if [ -f $i.bad ]
then
  retry=1
elif [ -f $i.ok ]
then
  if [ $filesize -eq 0 ]
  then
    retry=1
  fi
else
  retry=1
fi

if [ $retry -eq 1 ]
then
  # retry the download
fi

希望这有帮助!

于 2012-05-27T23:23:21.893 回答
0

我不知道你的连接是什么类型的,当前连接数过多会导致丢包。还要考虑服务器有什么样的连接。如果这不是内部服务器,则托管服务器的一方可能会认为这是拒绝服务攻击并过滤您的 IP。一个一个地做比较靠谱。瓶颈几乎总是互联网连接,你不能更快地做到这一点。

于 2012-05-27T23:58:11.607 回答