wget下载没有完成所有页面

时间:2012-05-27 23:01:13

标签: linux bash curl for-loop wget

我需要在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是下载页面的更好选择 是吗?

2 个答案:

答案 0 :(得分: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文件,并且可能部分下载该页面。

    < / LI>

在任何情况下,只有.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

希望这有帮助!

答案 1 :(得分:0)

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