私がやっていること:
私は「webscraper」(マルチスレッド) を開発しています。
ページからデータを抽出する前にフォームを送信する必要があるため、レイアウトは次のようになります。
- example.com/path/doc.jsp (私のデータ) への GET リクエスト。
- ドキュメント ソースに確認フォームが存在するかどうかを確認します。はいの場合はステップ 3 に進み (データが存在しないため、最初にフォームを送信する必要があります)、そうでない場合は戻ります (送信するフォームがなく、データがここにあるため)。
- example.com/path/sub/other.jsp への GET リクエスト (必要なキー値)。
- example.com/path/submit.jsp への POST 要求 (値の送信)。
- POST リクエストからの応答を確認し、OK の場合は 6 に進み、そうでない場合は 1 に戻ります。
- example.com/path/doc.jsp への GET リクエスト (再び私のデータ。フォームを送信したため、私のデータが表示されます)。
POST リクエスト (ステップ 4) からの応答でステップ 1 に戻るように指示された場合を除いて、すべて正常に動作しています。
問題:
フォーム内の値の 1 つを Cookie から抽出する必要があるため、GetCookies()
関数を使用しますが、前述のように、応答でステップ 1 に戻るように指示された場合、すべての要求 (GET と POST の両方) )その後、Cookieが欠落しています(そして奇妙なものが追加されました)。以下の画像を参照してください。
- 最初の呼び出しは、私のデータがある doc.jsp への GET 要求です。
- 2 番目の呼び出しは、確認フォームが doc.jsp ソース コードに存在するため、other.jsp 要求です。
- 3 番目の呼び出しは、すべての値を送信するときです。
- 4 回目の呼び出しは、doc.jsp への GET 要求です。これは、送信フォームの応答 (3 回目の呼び出し) でプロセスを繰り返すように指示されたためです。基本的に、4º ~ 6º の呼び出しは 1º ~ 3º と同じですが、cookie が fu**ed されています。
私のコード:
public class CWeb : IDisposable
{
private WebClientEx _wc;
private string _originalUrl;
public CWeb()
{
_wc = new WebClientEx(new CookieContainer());
}
public string downloadPage(string url)
{
_originalUrl = url;
string pgSrc = "error";
int tries = 0;
while (tries < 3 && pgSrc == "error)
{
try
{
pgSrc = _wc.DownloadString(url);
}
catch (Exception err)
{
tries += 1;
pgSrc = "error";
...
}
}
if (needSubmit(pgSrc)) // needSubmit just peform IndexOf on pgSrc
do
{
pgSrc = sendForm(pgSrc);
} while (needSubmit(pgSrc));
return WebUtility.HtmlDecode(pgSrc);
}
public string sendForm(pageSource)
{
// 1- Get Cookie Value
string cookie = _wc.CookieContainer.GetCookies(new Uri(_originalUrl))["JSESSIONID"].Value;
// 2- Get hidden values in pageSource parameter
// skip this, since there's no web request here, only some html parsing
// with Html Agility Pack
...
// 3- Get key value
string tmpStr = _wc.DownloadString("http://example.com/path/sub/other.jsp");
... more html parsing ...
// 4- Build form
NameValueCollection nvc = new NameValueCollection();
nvc["param1"] = cookie;
nvc["param2"] = key;
...
// 5- Send
_wc.UploadValues("example.com/path/submit.jsp", nvc);
// 6- Return
return _wc.DownloadString(_originalUrl);
}
public void Dispose()
{
_wc.Dispose();
}
}
主なプログラム:
static void Main(string[] args)
{
// Load tons of 'doc' url list from database...
List<string> urls = new List<string>();
...
Parallel.ForEach(urls, (url) =>
{
using (CWeb crawler = new CWeb())
{
string pageData = crawler.downloadPage(url);
... parse html data here ...
}
});
}
私の環境:
- Visual Studio Professional 2013 を使用しています。
- ターゲット フレームワークは .NET Framework 4.5 です。
- プラットフォーム x86 (デバッグ)。
- WebClientEx は、Cookie を操作するための WebClient の拡張バージョンです。ここから入手 PasteBin。
BugFix_CookieDomain()
(この質問から)を実装しようとしましたが、その修正を行っても、この問題は引き続き発生します。 すべての URL に http:// プレフィックスが含まれています。
Fiddler を使用してリクエスト情報を確認しました。
- 英語は私の母国語ではありません... '-'