HttpWebRequest:x-www-form-enclosedでWebRequestを使用してCanada Postで郵便番号を見つける方法
-
22-07-2019 - |
質問
現在、Windowsフォームを介したインターネットとのやり取りのスキルを向上させるために、いくつかのテストを書いています。これらのテストの1つは、カナダ郵便Webサイトから返される郵便番号を見つけることです。
- デフォルトのURL設定は、 http:/に設定されています。 /www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- 必要なフォームフィールドは、 streetNumber 、 streetName 、 city 、 province です。
- contentTypeは" application / x-www-form-enclosed"
編集:値" application / x-www-form-encoded"を考慮してください。 contentTypeとしてのポイント3値の代わりに。 (EricLaw-MSFTに感謝します!)
私が得る結果は期待した結果ではありません。郵便番号を見つけるための情報を手動で入力できるページのHTMLソースコードを取得しましたが、見つかった郵便番号を含むHTMLソースコードは取得できません。私が間違っていることのアイデアはありますか?
XMLの方法を検討しますか? Canada Postで匿名で検索することはまず可能ですか?
より良い説明のためのコードサンプルを次に示します。
public static string FindPostalCode(ICanadadianAddress address) {
var postData = string.Concat(string.Format("&streetNumber={0}", address.StreetNumber)
, string.Format("&streetName={0}", address.StreetName)
, string.Format("&city={0}", address.City)
, string.Format("&province={0}", address.Province));
var encoding = new ASCIIEncoding();
byte[] postDataBytes = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create(DefaultUrlSettings);
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Anonymous;
request.Container = new CookieContainer();
request.Timeout = 10000;
request.ContentType = contentType;
request.ContentLength = postDataBytes.LongLength;
request.Method = @"post";
var senderStream = new StreamWriter(request.GetRequestStream());
senderStream.Write(postDataBytes, 0, postDataBytes.Length);
senderStream.Close();
string htmlResponse = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
return processedResult(htmlResponse); // Processing the HTML source code parsing, etc.
}
自分の観点からすると、ボトルネックに引っかかっているようです。希望する結果に到達する方法が見つかりません。
編集:このサイトのContentTypeに関してはパラメーターが必要なようです。説明させてください。
- 次のことを規定する" meta"変数を持つものがあります:
meta http-equiv =" Content-Type" content =" application / xhtml + xml、 text / xml、text / html; charset = utf-8"
- また、コードの下位にある別のコード:
form id =" fpcByAdvancedSearch:fpcSearch" name =" fpcByAdvancedSearch:fpcSearch" method =" post" action =" / cpotools / apps / fpc / personal / findByCity?execution = e1s1" enctype =" application / x-www-form-urlencoded"
私の質問は次のとおりです。どちらに固執する必要がありますか?
最初のContentTypeは、関数への別のリクエストのみに使用されるため、最初のContentTypeは考慮されますか?
編集:リクエストに応じて、私が現在のソリューションに近い方がこの質問の下にリストされています。 WebRequest:を見つける方法このContentType =” application / xhtml + xml、text / xml、text / htmlに対してWebRequestを使用する郵便番号。 charset = utf-8”?
ご協力ありがとうございます! :-)
解決
WebClientクラスを使用していない理由を確認しようとしています:-
var fields = new NameValueCollection();
fields.Add("streetnumber", address.StreetNumber);
fields.Add("streetname", address.StreetName);
fields.Add("city", address.City);
fields.Add("province", address.Province);
var wc = new WebClient();
byte[] resultData = wc.UploadValues(url, fields);
string result = Encoding.Default.GetString(resultData);
UTF-8を使用する場合、結果の送信時にサーバーが使用するエンコードを確認することをお勧めします。最後の行を次のように変更します。-
string result = Encoding.UTF8.GetString(resultData);
元のコードで見つけた問題:-
- 最初のフィールドの先頭には&が付いていますが、これは存在しないはずです。
- 各フィールド値で
Uri.EscapeDataString
を使用して呼び出す必要があります。 -
GetRequestStream
の結果の周りにメモリストリームを構築しようとしています。MemoryStream
にそのようなコンストラクタがあったとしても、それが何を達成するかわかりません。とにかく。GetRequestStream
によって返されたストリームに直接書き込むだけです
すでに完了している場合は、フィドラーのコピーを入手して、標準フォームがデータを正常にリクエストし、コードが何をしているのか。
編集:Cookieコンテナの欠如がWebClientが動作しない原因であるという証拠がある場合、このアプローチを試すことができます:-
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
今、上記のコードを使用して、代わりに WebClient
インスタンス MyWebClient
をインスタンス化します。
他のヒント
HTTPWebRequestは、リクエストされたURLのコンテンツを返します。 HTMLページの場合、HTMLマークアップを返します。ページコンテンツがXMLの場合、XMLマークアップを返します。
Webサービスが必要なようです。そのタイプのリクエストを処理するために利用可能なウェブサービスがそのサイトにあるかどうかを確認します。含まれている場合、クエリへの応答としてXML、JSONマークアップが返されます。それ以外の場合は、リクエストの出力を解析する必要があります。