WebRequest: كيفية العثور على الرمز البريدي باستخدام WebRequest مقابل هذا contenttype = "التطبيق / XHTML + XML، النص / XML، النص / HTML؛ Charset = UTF-8 "؟

StackOverflow https://stackoverflow.com/questions/1455567

سؤال

أرسلت لأول مرة هذا: HttpWebRequest: كيفية العثور على الرمز البريدي في كندا بوست من خلال WebRequest مع X-WWW- النموذج المرفقة؟.

بعد اقتراحات Anthonywjones، غيرت التعليمات البرمجية بعد اقتراحاته.

بناء على استمرار استفساري، لاحظت مع الوقت الذي من المرجح أن يكون نوع المحتوى من كندا آخر "تطبيق / XHTML + XML، النص / XML، النص / HTML؛ Charset = UTF-8".

أسئلتي هي:

  1. كيف نكون WebRequest ضد هذا الموقع من نوع المحتوى؟
  2. هل يتعين علينا الاستمرار في الذهاب مع كائن NameValuecollection؟
  3. وفقا ل Scott Lance الذي قدم لي بسخاء معلومات ثمينة ضمن سؤالي السابق، يجب أن يعيد WebRequest نوع المعلومات مهما كان قد يكون نوع المحتوى، هل أنا أفتقد شيئا هنا؟
  4. هل يجب علي تغيير التعليمات البرمجية الخاصة بي بسبب تغيير نوع المحتوى؟

هنا هو رمزي بحيث قد يكون من الأسهل فهم تقدمي.

internal class PostalServicesFactory {
/// <summary>
/// Initializes an instance of GI.BusinessSolutions.Services.PostalServices.Types.PostalServicesFactory class.
/// </summary>
internal PostalServicesFactory() {
}
/// <summary>
/// Finds a Canadian postal code for the provided Canadian address.
/// </summary>
/// <param name="address">The instance of GI.BusinessSolutions.Services.PostalServices.ICanadianCityAddress for which to find the postal code.</param>
/// <returns>The postal code found, otherwise null.</returns>
internal string FindPostalCode(ICanadianCityAddress address) {
    if (address == null)
        throw new InvalidOperationException("No valid address specified.");

    using (ServicesWebClient swc = new ServicesWebClient()) {
        var values = new System.Collections.Specialized.NameValueCollection();

        values.Add("streetNumber", address.StreetNumber.ToString());
        values.Add("numberSuffix", address.NumberSuffix);
        values.Add("suite", address.Suite);
        values.Add("streetName", address.StreetName);
        values.Add("streetDirection", address.StreetDirection);
        values.Add("city", address.City);
        values.Add("province", address.Province);

        byte[] resultData = swc.UploadValues(@"http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity", "POST", values);

        return Encoding.UTF8.GetString(resultData);
    }
}

private class ServicesWebClient : WebClient {
    public ServicesWebClient()
        : base() {
    }
    protected override WebRequest GetWebRequest(Uri address) {
        var request = (HttpWebRequest)base.GetWebRequest(address);
        request.CookieContainer = new CookieContainer();
        return request;
    }
}
}

يؤدي هذا الرمز في الواقع إلى إرجاع رمز مصدر HTML للنموذج المرء ملء المعلومات المطلوبة من أجل معالجة مع البحث الرمز البريدي. ما أتمنى هو الحصول على شفرة مصدر HTML أو كل ما قد يكون مع الرمز البريدي الموجود.

تعديل: إليك WebException أحصل عليها الآن: "غير قادر على إرسال جسم محتوى مع هذا النوع من الفعل." (هذه ترجمة من الاستثناء الفرنسي "المستحيل D'Evoyer Un Corps de Contenu Avec CE Type de Verbe.")

إليك الرمز الخاص بي:

    internal string FindPostalCode(string url, ICanadianAddress address) {
    string htmlResult = null;

    using (var swc = new ServiceWebClient()) {
        var values = new System.Collections.Specialized.NameValueCollection();

        values.Add("streetNumber", address.StreetNumber.ToString());
        values.Add("numberSuffix", address.NumberSuffix);
        values.Add("suite", address.Suite);
        values.Add("streetName", address.StreetName);
        values.Add("streetDirection", address.StreetDirection);
        values.Add("city", address.City);
        values.Add("province", address.Province);

        swc.UploadValues(url, @"POST", values);
        string redirectUrl = swc.ResponseHeaders.GetValues(@"Location")[0];
        => swc.UploadValues(redirectUrl, @"GET", values);
    }

    return htmlResult;
}

يشير الخط الذي يؤدي إلى الاستثناء مع "=>". يبدو أنني لا أستطيع استخدام الحصول على الأسلوب، ومع ذلك، فهذا هو ما أخبرني أن أفعل ...

أي فكرة عما أفتقده هنا؟ أحاول أن أفعل ما أوصى لي جاستن (انظر الإجابة) لي.

شكرا مقدما على أي مساعدة! :-)

هل كانت مفيدة؟

المحلول

كإجراء مقدمة لعالم كشط الشاشة، لقد اخترت حالة صعبة للغاية! صفحة بحث بوست كندا تعمل مثل هذا:

  1. الصفحة الأولى هي نموذج يقبل قيم العناوين
  2. تنشر هذه الصفحة إلى عنوان URL الثاني.
  3. هذا عنوان URL الثاني بدوره يعيد توجيهات إعادة توجيه (باستخدام إعادة توجيه HTTP 302) إلى عنوان URL الثالث الذي يوضح لك بالفعل استجابة HTML التي تحتوي على الرمز البريدي.

مما يجعل الأمور أسوأ، تحتاج الصفحة في الخطوة رقم 3 إلى معرفة ملف تعريف الارتباط في الخطوة رقم 1. لذلك تحتاج إلى استخدام نفسه CookieContainer لجميع الطلبات الثلاث (على الرغم من أنه قد يكون كافيا لإرسال نفسه CookieContainer إلى # 2 و # 3 فقط).

علاوة على ذلك، قد تحتاج إلى إرسال رؤوس HTTP إضافية في هذه الطلبات أيضا، مثل قبول. أظن أن تكون في مشاكل في المشكلات هو أن HttpWebRequest عن طريق المقابض الافتراضية إعادة توجيه شفافة لك - ولكن عندما يعيد توجيهه بشفافية، فقد لا يضيف رؤوس HTTP اليمنى من الضروري لفتح المستعرض.

الحل هو ضبط HttpWebRequestAllowAutoRedirect الممتلكات إلى false، والتعامل مع إعادة توجيه نفسك. وبعبارة أخرى، بمجرد إرجاع الطلب الأول إعادة توجيه، ستحتاج إلى سحب عنوان URL في HttpWebResponseLocation: رأس. ثم ستحتاج إلى إنشاء جديد HttpWebRequest (هذه المرة الحصول على طلب منتظم، وليس منشور) لهذا عنوان URL. تذكر لإرسال ملف تعريف الارتباط نفسه! (ال CookieContainer الطبقة تجعل هذا سهل جدا)

قد تحتاج أيضا إلى تقديم طلب إضافي (# 1 في قائمتي أعلاه) من أجل إعداد ملف تعريف ارتباط الجلسة. إذا كنت أنت، فستفترض أن هذا مطلوب، ببساطة القضاء عليه بمثابة مشكلة، وحاول إزالة تلك الخطوة لاحقا ومعرفة ما إذا كان حلك لا يزال يعمل.

سترغب في تنزيل واستخدام FIDLLER (www.fiddlertool.com.) لمساعدتك في كل هذا. يسمح لك FIDDLer بمشاهدة طلبات HTTP التي تسير عبر السلك، وتتيح لك (عبر ميزة Builder) بإنشاء طلبات HTTP حتى تتمكن من رؤية الرؤوس المطلوبة بالفعل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top