Google+1、Facebook の共有、ツイート用に Web サイトをスクレイピングするアプリを開発しています。URL を受け取り、ソーシャル メディアの種類ごとにカウントを取得するリクエスト メソッドがあります。
そのロジックは次のとおりです。
- URLを取る
- レート制限された/500 以外の応答が得られるまで、ローカル/デフォルト IP を介して要求を行います
- エラー時
SelectNewProxy()
プロキシのリストを繰り返し処理し、ランダムに 1 つを返す呼び出し(IP のリクエスト制限を回避する良い方法)- リストから不適切なプロキシを削除して、再度選択しないようにします
- 毎秒インクリメントするタイマーを開始する
- タイマー == 600 (10 分) の場合
- 新規作成
WebProxy
し、ローカル/デフォルト IP の背後にあるリクエストを再度試行します - タイマーをリセット
- 新規作成
すすいで繰り返す
コードは次のとおりです。
public string Request(string action)
{
HttpWebRequest req;
OnStatusChange(new MyArgs() { Message = "Status: Requesting..." });
string response = string.Empty;
while (response.Equals(string.Empty) && proxy != null)
{
try
{
req = (HttpWebRequest)WebRequest.Create(action);
req.Proxy = proxy;
HandleUIMessages(action, proxy);
response = new StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd();
}
catch
{
//OnProxyChange(new MyArgs() { ProxyMessage = string.Format("Proxy: {0}", proxy.Address.ToString()) });
RemoveProxy(proxy);
if (!timer.Enabled)
{
timer.Interval = (int)TimeInterval.OneSecond;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled = true;
timer.Start();
}
WebProxy reset = new SelectNewProxy();
proxy = counter >= 600 ? reset : proxy = SelectNewProxy();
}
}
return response;
}
私が使用していてThreadPool
、各リクエストが独自のスレッドで実行されていることに言及する価値があります。機能するようですが、目的の効果が得られません。カウンターは「600」に達して設定されますproxy = reset
が、それは非常に短時間しか行わないように見えます。おそらく最初にヒットしたスレッドのみですか? その後、timer_Elapsed
が呼び出されcounter
てリセットされます。スレッドがヒットし、割り当てproxy = reset
てから、リセットされたためcounter
(>= 600 ではなくなった)、後続のキューに入れられたすべてのスレッドが を呼び出す可能性がありSelectNewProxy()
ますか? とりとめのないように感じますが、誰かが私が言おうとしていることを理解してくれることを願っています。私の推測が正しければ、すべてのスレッドがproxy = reset
最初の IP を取得して再試行できるようにするにはどうすればよいですか?
どんな助けでも大歓迎です!
ありがとうございました