0

私がやっていること:
私は「webscraper」(マルチスレッド) を開発しています。
ページからデータを抽出する前にフォームを送信する必要があるため、レイアウトは次のようになります。

  1. example.com/path/doc.jsp (私のデータ) への GET リクエスト。
  2. ドキュメント ソースに確認フォームが存在するかどうかを確認します。はいの場合はステップ 3 に進み (データが存在しないため、最初にフォームを送信する必要があります)、そうでない場合は戻ります (送信するフォームがなく、データがここにあるため)。
  3. example.com/path/sub/other.jsp への GET リクエスト (必要なキー値)。
  4. example.com/path/submit.jsp への POST 要求 (値の送信)。
  5. POST リクエストからの応答を確認し、OK の場合は 6 に進み、そうでない場合は 1 に戻ります。
  6. 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 の拡張バージョンです。ここから入手 PasteBinBugFix_CookieDomain()この質問から)を実装しようとしましたが、その修正を行っても、この問題は引き続き発生します。
  • すべての URL に http:// プレフィックスが含まれています。

  • Fiddler を使用してリクエスト情報を確認しました。

  • 英語は私の母国語ではありません... '-'
4

1 に答える 1

0

私はSystem.Net.WebRequestをあなたがしていることに似たものに使用します。これは、CookieContainer というプロパティを介して Http (WebRequest の HttpWebRequest サブクラス) を使用するときに Cookie を処理します。Cookie が追加され、Cookie コンテナーからも明らかに削除されていることに気付きました。私の考えでは、これはサーバー側 (リクエスト先の Web アプリ) によって完全に制御されています。追加のクッキーを追加することができます。

さらに、Cookie に有効期限、破棄フラグ、およびドメインがある場合、有効期限が過ぎた場合、サーバーが破棄フラグを設定するか、ドメインが変更された場合、適用可能な Cookie のリストが変更される可能性があります。

これが役立つかどうかはわかりませんが、試してみます。

于 2016-01-11T23:37:31.040 に答える