Webから情報を取得するサンプル(郵便番号から住所検索)

2023年2月10日

インターネット上のデータを取得して、処理をするサンプルプログラムになります

郵便番号から住所を取得する

.NETを想定しています
System.Text.Jsonのライブラリを使っています
NewtonSoftのライブラリを使わないサンプルです

コード

using System.Text.Json;
using System.Text.Json.Serialization;

var zipCode = "107-0052";
var apiUrl = "https://zipcloud.ibsnet.co.jp/api/search";
var url = $"{apiUrl}?zipcode={zipCode}";

var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
var jsonString = await response.Content.ReadAsStringAsync();

var json = JsonSerializer.Deserialize<ZipCodeResult>(jsonString);

if (json.Status == 200)
{
    Console.WriteLine("都道府県: " + json.Results[0].Prefecture);
    Console.WriteLine("市区町村: " + json.Results[0].City);
    Console.WriteLine("町域: " + json.Results[0].Town);
}
else
{
    Console.WriteLine("該当する住所が見つかりませんでした。");
}

class ZipCodeResult
{
    [JsonPropertyName("status")]
    public int Status { get; set; }

    [JsonPropertyName("message")]
    public string Message { get; set; }

    [JsonPropertyName("results")]
    public ZipCodeAddress[] Results { get; set; }
}

class ZipCodeAddress
{
    [JsonPropertyName("address1")]
    public string Prefecture { get; set; }

    [JsonPropertyName("address2")]
    public string City { get; set; }

    [JsonPropertyName("address3")]
    public string Town { get; set; }

    [JsonPropertyName("kana1")]
    public string Kana1 { get; set; }

    [JsonPropertyName("kana2")]
    public string Kana2 { get; set; }

    [JsonPropertyName("kana3")]
    public string Kana3 { get; set; }

    [JsonPropertyName("prefcode")]
    public string PrefCode { get; set; }

    [JsonPropertyName("zipcode")]
    public string ZipCode { get; set; }
}

実行結果

都道府県: 東京都
市区町村: 港区
町域: 赤坂

このコードは、郵便番号を入力し、その郵便番号に対応する住所を取得するC#のコードです。

  • zipCode 変数に郵便番号を代入しています。
  • apiUrl 変数には、郵便番号検索のAPIのURLを代入しています。
  • url 変数には、郵便番号を含めたAPIのURLを作成しています。
  • HttpClient クラスを使用してAPIを呼び出し、応答を response 変数に格納しています。
  • ReadAsStringAsync メソッドを使用して、応答のコンテンツを文字列として取得し、jsonString 変数に格納しています。
  • JsonSerializer.Deserialize メソッドを使用して、jsonString 変数をZipCodeResult 型にデシリアル化し、json 変数に格納しています。
  • json.Status プロパティが200である場合、取得した住所(都道府県、市区町村、町域)をコンソールに出力します。それ以外の場合、該当する住所が見つからなかったことを示すメッセージを出力します。
  • ZipCodeResult クラスと ZipCodeAddress クラスは、応答の結果を表すモデルクラスです。

これらの2つのクラスは、JSONデータを扱うためのモデルです。

JsonPropertyName 属性を使用することで、JSONデータのフィールド名とクラスのプロパティ名を対応付けます。

  • ZipCodeResult クラスは、APIから返されたレスポンスを表します。各プロパティには、JSONのフィールドに対応する名前が設定されています(例:Statusプロパティは"status"フィールドに対応)。
  • ZipCodeAddress クラスは、各住所に関する情報を表します。各プロパティは、住所に関連する情報(例:県、市、町など)に対応します。

Jsonのデータ

{
	"message": null,
	"results": [
		{
			"address1": "東京都",
			"address2": "港区",
			"address3": "赤坂",
			"kana1": "トウキョウト",
			"kana2": "ミナトク",
			"kana3": "アカサカ",
			"prefcode": "13",
			"zipcode": "1070052"
		}
	],
	"status": 200
}

ブレークポイントで実行中に郵便番号データを取得している様子を確認する

ブレークポイントを置いて、実際に取得されているJsonデータをビジュアルに確認する機能を試してみましょう

Jsonフォーマットのデータから抽出用クラスを作成する様子を確認する

学習のため、継承とポリモーフィズムを使ったコード

using System.Text.Json;
using System.Text.Json.Serialization;

var zipCode = "107-0052";
var apiUrl = "https://zipcloud.ibsnet.co.jp/api/search";
var url = $"{apiUrl}?zipcode={zipCode}";

var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
var jsonString = await response.Content.ReadAsStringAsync();

var zipCodeResult = JsonSerializer.Deserialize<ZipCodeResult>(jsonString);

if (zipCodeResult.IsSuccessful)
{
    Console.WriteLine(zipCodeResult.Address.ToString());
}
else
{
    Console.WriteLine(zipCodeResult.Message);
}

abstract class ZipCodeResultBase
{
    public int Status { get; set; }

    public string Message { get; set; }

    public abstract bool IsSuccessful { get; }
}

class ZipCodeResult : ZipCodeResultBase
{
    [JsonPropertyName("results")]
    public ZipCodeAddress[] Results { get; set; }

    public override bool IsSuccessful => Status == 200;

    public ZipCodeAddress Address => Results[0];
}

class ZipCodeAddress
{
    [JsonPropertyName("address1")]
    public string Prefecture { get; set; }

    [JsonPropertyName("address2")]
    public string City { get; set; }

    [JsonPropertyName("address3")]
    public string Town { get; set; }

    public override string ToString()
    {
        return $"都道府県: {Prefecture}\n市区町村: {City}\n町域: {Town}";
    }
}

このコードはAPIから取得した住所情報に基づいて、都道府県、市区町村、町域を出力するものです。

例えば、APIから取得した住所情報が正常に取得された場合、次のような出力が得られます:

都道府県: 東京都
市区町村: 港区
町域: 赤坂

APIから取得した住所情報が存在しない場合、次のような出力が得られます:

該当する住所が見つかりませんでした。

WindowsFormアプリにした場合

VisualStudioのフォームデザイン画面

textBox1のイベント画面

入力都度イベントが発生します

コード

using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;

namespace WeatherNet7
{
    public partial class Form1 : Form
    {
        private readonly string _apiUrl = "https://zipcloud.ibsnet.co.jp/api/search";

        public Form1()
        {
            InitializeComponent();
        }

        private  void TextBox1_TextChanged(object sender, EventArgs e)
        {
            CheckZip();
        }


        private async void CheckZip()
        {
            var zipCode = textBox1.Text;
            textBox2.Text = "検索中";

            var zipCodeResult = await GetZipCodeResult(zipCode);
            if (zipCodeResult == null || zipCodeResult.Address == null)
            {
                textBox2.Text = "";
                return;
            }

            textBox2.Text = zipCodeResult.Address[0].Prefecture + zipCodeResult.Address[0].City + zipCodeResult.Address[0].Town;
        }

        private async Task<ZipCodeResult> GetZipCodeResult(string zipCode)
        {
            if (!IsValidPostalCode(zipCode))
                return null;

            var url = $"{_apiUrl}?zipcode={zipCode}";

            using (var httpClient = new HttpClient())
            {
                var response = await httpClient.GetAsync(url);
                var jsonString = await response.Content.ReadAsStringAsync();

                var json = JsonSerializer.Deserialize<ZipCodeResult>(jsonString);

                if (json.Status == 200)
                    return json;
            }

            return null;
        }

        private bool IsValidPostalCode(string postalCode)
        {
            string pattern = @"^\d{3}-?\d{4}$";
            return Regex.IsMatch(postalCode, pattern);
        }

        class ZipCodeResult
        {
            [JsonPropertyName("status")]
            public int Status { get; set; }

            [JsonPropertyName("message")]
            public string Message { get; set; }

            [JsonPropertyName("results")]
            public ZipCodeAddress[] Address { get; set; }
        }

        class ZipCodeAddress
        {
            [JsonPropertyName("address1")]
            public string Prefecture { get; set; }

            [JsonPropertyName("address2")]
            public string City { get; set; }

            [JsonPropertyName("address3")]
            public string Town { get; set; }

            [JsonPropertyName("kana1")]
            public string Kana1 { get; set; }

            [JsonPropertyName("kana2")]
            public string Kana2 { get; set; }

            [JsonPropertyName("kana3")]
            public string Kana3 { get; set; }

            [JsonPropertyName("prefcode")]
            public string PrefCode { get; set; }

            [JsonPropertyName("zipcode")]
            public string ZipCode { get; set; }
        }
    }
}

天気予報Webアクセスサンプル

WindowsFormアプリを想定したプログラムになります
これは、ダミーのデータになりますので、実在するAPIを呼び出しているわけではありません

using System.Text.Json;
using System.Text.Json.Serialization;

namespace WeatherChecker
{
    public partial class Form1 : Form
    {
        Dictionary<string, string> cityNames;

        public Form1()
        {
            InitializeComponent();

            this.cityNames = new Dictionary<string, string>();

            this.cityNames.Add("東京都", "3");
            this.cityNames.Add("大阪府", "1");
            this.cityNames.Add("愛知県", "2");
            this.cityNames.Add("福岡県", "10");

            foreach (KeyValuePair<string, string> data in this.cityNames)
            {
                areaBox.Items.Add(data.Key);
            }
        }

        private void CitySelected(object sender, EventArgs e)
        {
            // 天気情報サービスにアクセスする
            string cityCode = cityNames[areaBox.Text];
            string url = "天気予報Web.php?city=" + cityCode;
            HttpClient client = new HttpClient();
            string result = client.GetStringAsync(url).Result;

            // JSONデータをWeatherDataクラスに変換
            WeatherData weatherData = JsonSerializer.Deserialize<WeatherData>(result);
            weatherIcon.ImageLocation = weatherData.WeatherIcon;
        }

        private void ExitMenuClicked(object sender, EventArgs e)
        {
            // フォームを閉じる
            this.Close();
        }
    }

    public class WeatherData
    {
        [JsonPropertyName("city")]
        public string City { get; set; }

        [JsonPropertyName("weather")]
        public string Weather { get; set; }

        [JsonPropertyName("location")]
        public Location Location { get; set; }

        [JsonPropertyName("percent")]
        public string Percent { get; set; }

        [JsonPropertyName("Humidity")]
        public string Humidity { get; set; }

        [JsonPropertyName("temp")]
        public string Temperature { get; set; }

        [JsonPropertyName("wind")]
        public string Wind { get; set; }

        [JsonPropertyName("pressure")]
        public string Pressure { get; set; }

        [JsonPropertyName("url")]
        public string WeatherIcon { get; set; }
    }

    public class Location
    {
        [JsonPropertyName("longitude")]
        public string Longitude { get; set; }

        [JsonPropertyName("latitude")]
        public string Latitude { get; set; }
    }
}

解説

このコードは、天気情報を表示するWindowsフォームアプリケーションの部分です。

  • Form1クラス:
    • コンストラクタでは、cityNames辞書を初期化し、都市名を収納します。
    • CitySelectedメソッドは、都市名が選択されたときに呼び出されます。このメソッドでは、天気情報サービスにアクセスし、取得したJSONデータをWeatherDataクラスに変換します。変換したWeatherDataオブジェクトから、天気アイコンのURLを取得し、ImageLocationプロパティに設定します。
    • ExitMenuClickedメソッドは、「終了」メニューがクリックされたときに呼び出されます。このメソッドでは、フォームを閉じます。
  • WeatherDataクラス:
    • JSONデータから天気情報を表すプロパティを持つクラスです。各プロパティは、[JsonPropertyName]属性でJSONデータとマッピングされます。
  • Locationクラス:
    • JSONデータから都市の緯度経度情報を表すプロパティを持つクラスです。各プロパティは、[JsonPropertyName]属性でJSONデータとマッピングされます。
namespace WeatherApp
{
    partial class Form1
    {
        /// <summary>
        /// 必要なデザイナー変数です。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 使用中のリソースをすべてクリーンアップします。
        /// </summary>
        /// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows フォーム デザイナーで生成されたコード

        /// <summary>
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.areaBox = new System.Windows.Forms.ComboBox();
            this.weatherIcon = new System.Windows.Forms.PictureBox();
            this.label1 = new System.Windows.Forms.Label();
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.ファイルToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.終了ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            ((System.ComponentModel.ISupportInitialize)(this.weatherIcon)).BeginInit();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // areaBox
            // 
            this.areaBox.FormattingEnabled = true;
            this.areaBox.Location = new System.Drawing.Point(64, 361);
            this.areaBox.Name = "areaBox";
            this.areaBox.Size = new System.Drawing.Size(285, 32);
            this.areaBox.TabIndex = 0;
            this.areaBox.SelectedIndexChanged += new System.EventHandler(this.CitySelected);
            // 
            // weatherIcon
            // 
            this.weatherIcon.Location = new System.Drawing.Point(438, 74);
            this.weatherIcon.Name = "weatherIcon";
            this.weatherIcon.Size = new System.Drawing.Size(323, 319);
            this.weatherIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.weatherIcon.TabIndex = 1;
            this.weatherIcon.TabStop = false;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(60, 322);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(172, 24);
            this.label1.TabIndex = 2;
            this.label1.Text = "都道府県を選択";
            // 
            // menuStrip1
            // 
            this.menuStrip1.GripMargin = new System.Windows.Forms.Padding(2, 2, 0, 2);
            this.menuStrip1.ImageScalingSize = new System.Drawing.Size(32, 32);
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.ファイルToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(846, 40);
            this.menuStrip1.TabIndex = 3;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // ファイルToolStripMenuItem
            // 
            this.ファイルToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.終了ToolStripMenuItem});
            this.ファイルToolStripMenuItem.Name = "ファイルToolStripMenuItem";
            this.ファイルToolStripMenuItem.Size = new System.Drawing.Size(103, 38);
            this.ファイルToolStripMenuItem.Text = "ファイル";
            // 
            // 終了ToolStripMenuItem
            // 
            this.終了ToolStripMenuItem.Name = "終了ToolStripMenuItem";
            this.終了ToolStripMenuItem.Size = new System.Drawing.Size(359, 44);
            this.終了ToolStripMenuItem.Text = "終了";
            this.終了ToolStripMenuItem.Click += new System.EventHandler(this.ExitMenuClicked);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 24F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.SystemColors.Window;
            this.ClientSize = new System.Drawing.Size(846, 450);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.weatherIcon);
            this.Controls.Add(this.areaBox);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.weatherIcon)).EndInit();
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.ComboBox areaBox;
        private System.Windows.Forms.PictureBox weatherIcon;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem ファイルToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem 終了ToolStripMenuItem;
    }
}

C#,学習,設計

Posted by hidepon