1

Linuxで3万ページ以上をダウンロードする必要があり、単純な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."

一部のページが完全にダウンロードされていません!

  • 上記のコードは1kWgetを並列実行プロセスにし、プロセスを追加するためにそれが下がるまで待機するので、実際に利用可能なすべてのインターネットリンクを使い果たしている可能性がありますか?

  • ページが実際に正しくダウンロードされていることを確認するために、これをより信頼性の高いものにするにはどうすればよいですか?

編集:

  • ページをダウンロードするためのより良いオプションは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リターンコードで終了した場合)、ダウンロードされたページとファイルの2つのファイルが存在する必要があり.okます。

  • ダウンロードが失敗した場合(つまりwget、KOリターンコードを返す場合)、.badファイルが存在する必要があり、おそらくページの部分的なダウンロードが存在する必要があります。

いずれにせよ、.ok重要なのはファイルだけです。ダウンロードが正しく終了したと表示されます(wget観点から、これについては後で説明します)。

特定のページのファイルが見つからない場合.okは、確かにダウンロードされていないため、再試行する必要があります。

次に、手順の最もデリケートな部分に進みます。Webサーバーが、その大量のリクエストへの応答として、HTTP 200応答とゼロコンテンツ長で処理できないリクエストをキャンセルした場合はどうなりますか?これは、Webコピーやある種のサーバー攻撃を回避するための優れた手法です。

その場合は、応答のパターンを確認する必要があります。ファイルはあり.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をフィルタリングする可能性があります。1つずつ実行するだけで信頼性が高くなります。ボトルネックはほとんどの場合インターネット接続であり、これ以上速くすることはできません。

于 2012-05-27T23:58:11.607 に答える