Java と htmlunit の WebClient を使用してマルチスレッド スクレーパーを作成しています。私はプロキシのプールを使用しており、それらを処理するための単純なクラスがあります。プロキシのリストがあり、GetProxy 関数を呼び出して、リスト内の次のプロキシの IP とポートを取得します。徹底的にテストし、任意の数のスレッドで意図したとおりに動作することを確認しました。
そこから、URL とプロキシを渡すことができる getHTML 関数があり、ページが返されます。
public String getHTML(String URL, ProxyData pData)
{
WebClient webClient = new WebClient();
String pageAsXml = "";
webClient.setJavaScriptEnabled(false);
ProxyConfig pConf = new ProxyConfig(pData._host, pData._port);
webClient.setProxyConfig(pConf);
try
{
HtmlPage page = webClient.getPage(URL);
pageAsXml = page.asXml();
}
catch (FailingHttpStatusCodeException e)
{
e.printStackTrace();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
webClient.closeAllWindows();
return pageAsXml;
}
コードで WebClients プロキシ設定を設定した後、それらをコンソールに書き込むと、正しい IP のように見えます。デバッグ モードでステップ実行すると、これも確認されます。ただし、結果として返される HTML は、変更されたプロキシを反映していないようです。
WhatIsMyIP の自動化ページを使用して、プロキシが機能しているかどうかを確認しています (http://automation.whatismyip.com/n09230945.asp)。ページを取得するたびに、関数に渡したプロキシを記述します。プロキシ WebClient は、ページの読み込み時に使用していると言い、次に HTML で返されたプロキシをコンソールに返します。最初の 2 つは常に正常に一致しますが、返される IP はオフです。それらはすべて最初は正しいですが、その後プロキシを再利用し始めたようです。また、プロキシは常に同じスレッド内で再利用されるとは限りません。彼らは、すでに存在するランダムなプロキシを選択しているようです。
プロキシは、スレッド間であっても、実際に置き換えられる前にしばらくランダムに再利用されるようです。新しいプロキシを設定し、WebClient は新しいプロキシを設定したことを認識しているように見えますが、それでも古いプロキシを使用しているようです。
では、何が原因で、どうすれば回避できますか?