やりたいこと
Go言語の勉強の一環として、Yahoo!ショッピングの商品検索結果を取得するプログラミングを作成する。
環境
- Windows 11 Pro
- Go バージョン 1.22.4
事前準備
Yahoo!デベロッパーネットワークにアプリケーションを登録し、Client IDを取得する。
コード
main.go
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type Response struct {
TotalResultsAvailable int `json:"totalResultsAvailable"`
TotalResultsReturned int `json:"totalResultsReturned"`
FirstResultPosition int `json:"firstResultPosition"`
Request Request `json:"request"`
Hits []Hit `json:"hits"`
}
type Request struct {
Query string `json:"query"`
}
type Hit struct {
Index int `json:"index"`
Name string `json:"name"`
Description string `json:"description"`
HeadLine string `json:"headLine"`
URL string `json:"url"`
InStock bool `json:"inStock"`
Code string `json:"code"`
Condition string `json:"condition"`
ImageID string `json:"imageId"`
Image Image `json:"image"`
Review Review `json:"review"`
AffiliateRate float64 `json:"affiliateRate"`
Price int `json:"price"`
PremiumPrice int `json:"premiumPrice"`
PremiumPriceStatus bool `json:"premiumPriceStatus"`
PremiumDiscountType interface{} `json:"premiumDiscountType"`
PremiumDiscountRate interface{} `json:"premiumDiscountRate"`
PriceLabel PriceLabel `json:"priceLabel"`
Point Point `json:"point"`
Shipping Shipping `json:"shipping"`
GenreCategory GenreCategory `json:"genreCategory"`
ParentGenreCategories []GenreCategory `json:"parentGenreCategories"`
Brand Brand `json:"brand"`
ParentBrands []Brand `json:"parentBrands"`
JanCode string `json:"janCode"`
ReleaseDate interface{} `json:"releaseDate"`
Seller Seller `json:"seller"`
Delivery Delivery `json:"delivery"`
Payment string `json:"payment"`
}
type Image struct {
Small string `json:"small"`
Medium string `json:"medium"`
}
type Review struct {
Rate float64 `json:"rate"`
Count int `json:"count"`
URL string `json:"url"`
}
type PriceLabel struct {
Taxable interface{} `json:"taxable"`
DefaultPrice int `json:"defaultPrice"`
DiscountedPrice interface{} `json:"discountedPrice"`
FixedPrice interface{} `json:"fixedPrice"`
PremiumPrice interface{} `json:"premiumPrice"`
PeriodStart interface{} `json:"periodStart"`
PeriodEnd interface{} `json:"periodEnd"`
}
type Point struct {
Amount int `json:"amount"`
Times int `json:"times"`
PremiumAmount int `json:"premiumAmount"`
PremiumTimes int `json:"premiumTimes"`
}
type Shipping struct {
Code int `json:"code"`
Name string `json:"name"`
}
type GenreCategory struct {
ID int `json:"id"`
Name string `json:"name"`
Depth int `json:"depth"`
}
type Brand struct {
ID int `json:"id"`
Name string `json:"name"`
}
type Seller struct {
SellerID string `json:"sellerId"`
Name string `json:"name"`
URL string `json:"url"`
IsBestSeller bool `json:"isBestSeller"`
Review Review `json:"review"`
ImageID string `json:"imageId"`
}
type Delivery struct {
Area string `json:"area"`
DeadLine interface{} `json:"deadLine"`
Day interface{} `json:"day"`
}
func main() {
// Httpクライアント作成
client := http.Client{
Timeout: 30 * time.Second,
}
// URLクエリ作成
url := "https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid=[クライアントID]&query=[検索ワード]"
req, err := http.NewRequestWithContext(
context.Background(),
http.MethodGet,
url,
nil)
if err != nil {
panic(err)
}
// Httpリクエスト送信して結果を受け取る
req.Header.Add("X-My-Client", "Learning Go")
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
panic(fmt.Sprintf("unexpected status: got %v", res.Status))
}
fmt.Println(res.Header.Get("Content-Type"))
// レスポンスボディの文字列(json)を取得
buffer := make([]byte, 1024)
var jsonString string
for {
c, err := res.Body.Read(buffer)
if err != nil {
if err == io.EOF {
jsonString += string(buffer[:c])
break
}
print(err)
}
jsonString += string(buffer[:c])
}
fmt.Println(jsonString)
// json文字列を構造体に変換
var response Response
err1 := json.Unmarshal([]byte(jsonString), &response)
if err1 != nil {
fmt.Println("Error decoding JSON:", err1)
return
}
fmt.Printf("Parsed Response: %+v\n", response)
}
実行結果(jsonを整形したもの)
"totalResultsAvailable": 19112,
"totalResultsReturned": 20,
"firstResultsPosition": 1,
"request": {
"query": "なにか"
},
"hits": [
{
"index": 1,
"name": "[ネコポス送料無料]変形フレームパーツ 5個入り 枠 フレーム 土台 ネイルパーツ メタルパーツ マニキュア セルフネイル ジェルネイル",
"description": "【特徴】<br> 不揃いな形がおしゃれな<br> 『変形フレームパーツ』 が新登場!<br> <br> そのまま使っても、<br> 中になにか埋め込んで使ってもOK ◎<br> <br> 流行りのドゥルー ジーネイルも<br> ワンランク上の仕上がりに !<br> <br> 背面カーブ加工が施されているので<br> しっかり爪にフィットします ♪<br><br> <br> <br> 【サイズ】<br> 約10mm×6mm<br> (最大サイズ)<br> <br> 5個入り<br><br> <br> <br> 【カラー】<br> ゴールド<br><br> <br> <br> 【ネコポス】<br> 可 [ネコポス送料無料]<br> <br> <br> ■ネコポスをご利用の場合のご注意■<br> <br> ・ネコポスは手渡しではなくポストへ直接投函となります。<br> その為、代金引換や日時指定は出来ません。<br> 追跡サービス有り。<br> ・配達時の欠損・盗難・不達・延着などの<br> 保証がございません。詳しくは配送についてを<br> ご確認の上ご利用くださいますよう<br> お願い申し上げます。",
"headLine": "そのまま使っても中に埋め込んでも ◎",
"url": "https://store.shopping.yahoo.co.jp/deconail-seisakujo/loave-metalparts-440.html",
"inStock": true,
"code": "deconail-seisakujo_loave-metalparts-440",
"condition": "new",
"imageId": "deconail-seisakujo_loave-metalparts-440",
"image": {
"small": "https://item-shopping.c.yimg.jp/i/c/deconail-seisakujo_loave-metalparts-440",
"medium": "https://item-shopping.c.yimg.jp/i/g/deconail-seisakujo_loave-metalparts-440"
},
"review": {
"count": 32,
"url": "https://shopping.yahoo.co.jp/review/item/list?store_id=deconail-seisakujo&page_key=loave-metalparts-440",
"rate": 4.59
},
"affiliateRate": 7,
"price": 143,
"premiumPrice": 143,
"premiumPriceStatus": false,
"premiumDiscountRate": null,
"premiumDiscountType": null,
"priceLabel": {
"taxable": true,
"defaultPrice": 143,
"discountedPrice": null,
"fixedPrice": null,
"premiumPrice": null,
"periodStart": 1720746000,
"periodEnd": null
},
"point": {
"amount": 0,
"times": 0,
"bonusAmount": 1,
"bonusTimes": 1,
"premiumAmount": 0,
"premiumTimes": 0,
"premiumBonusAmount": 1,
"premiumBonusTimes": 1
},
"shipping": {
"code": 2,
"name": "送料無料"
},
"genreCategory": {
"id": 1826,
"name": "ラインストーン、パーツ",
"depth": 4
},
"parentGenreCategories": [
{
"id": 2501,
"depth": 1,
"name": "コスメ、美容、ヘアケア"
},
{
"id": 1809,
"depth": 2,
"name": "ネイル用品"
},
{
"id": 1821,
"depth": 3,
"name": "ネイルアート"
}
],
"brand": {
"id": 38074,
"name": "ブランド登録なし"
},
"parentBrands": [
{
"id": 1,
"name": "ブランド"
}
],
"janCode": "4589582646050",
"payment": "128 4096 8192 4 16 16384 2 256 512 8 1024 1 64",
"releaseDate": null,
"seller": {
"sellerId": "deconail-seisakujo",
"name": "ネイルタウン NAILTOWN",
"url": "https://store.shopping.yahoo.co.jp/deconail-seisakujo/",
"isBestSeller": false,
"review": {
"rate": 4.74,
"count": 12490
},
"imageId": "deconail-seisakujo_1"
},
"delivery": {
"deadLine": 10,
"day": 1,
"area": "13"
}
},
{
"index": 2,
"name": "【限定販売】【あみあみ限定特典】KDcolle『蜘蛛ですが、なにか?』 原作版 「私」アラクネ/白織 1/7 完成品フィギュア[KADOKAWA]《発売済・在庫品》",
"description": "※流通の都合により「中国」への販売はできません。 ※こちらの商品はあみあみ、他一部店舗限定での取り扱いとなります。 ※あみあみ限定特典が付きます。 <br>◆お一人様 2 点まで(本店支店合計)<br>※同一住所より複数件のご注文をいただいた場合、ご注文を取り消しさせていただくことがございます。<br>◆仕様:塗装済み完成品 【スケール】1/7 【サイズ】 全高約240mm 【素材】PVC<br>◆ブランド:KADOKAWA <br>◆原作:蜘蛛ですが、なにか? <br>◆キャラ:私(蜘蛛子/白/白織) <br>◆作家:あきもふ<br>◆検索ワード:nw210703 _00458 _00459 _09713 CTG001 b0003871 t025695 c0042967 ami_bonus",
"headLine": "",
"url": "https://store.shopping.yahoo.co.jp/amiami/figure-128049.html",
"inStock": true,
"code": "amiami_figure-128049",
"condition": "new",
"imageId": "amiami_figure-128049",
"image": {
"small": "https://item-shopping.c.yimg.jp/i/c/amiami_figure-128049",
"medium": "https://item-shopping.c.yimg.jp/i/g/amiami_figure-128049"
},
"review": {
"count": 7,
"url": "https://shopping.yahoo.co.jp/review/item/list?store_id=amiami&page_key=figure-128049",
"rate": 3.57
},
"affiliateRate": 1,
"price": 31350,
"premiumPrice": 31350,
"premiumPriceStatus": false,
"premiumDiscountRate": null,
"premiumDiscountType": null,
"priceLabel": {
"taxable": true,
"defaultPrice": 31350,
"discountedPrice": null,
"fixedPrice": null,
"premiumPrice": null,
"periodStart": 1639710000,
"periodEnd": null
},
"point": {
"amount": 0,
"times": 0,
"bonusAmount": 285,
"bonusTimes": 1,
"premiumAmount": 0,
"premiumTimes": 0,
"premiumBonusAmount": 285,
"premiumBonusTimes": 1
},
"shipping": {
"code": 1,
"name": "設定なし"
},
"genreCategory": {
"id": 2137,
"name": "その他コミック、アニメフィギュア",
"depth": 4
},
"parentGenreCategories": [
{
"id": 2511,
"depth": 1,
"name": "ゲーム、おもちゃ"
},
{
"id": 15160,
"depth": 2,
"name": "フィギュア"
},
{
"id": 17085,
"depth": 3,
"name": "コミック、アニメーションフィギュア"
}
],
"brand": {
"id": 59518,
"name": "KADOKAWA"
},
"parentBrands": [
{
"id": 1,
"name": "ブランド"
}
],
"janCode": "4935228288724",
"payment": "16 16384 4096 1 2 4",
"releaseDate": null,
"seller": {
"sellerId": "amiami",
"name": "あみあみ Yahoo!店",
"url": "https://store.shopping.yahoo.co.jp/amiami/",
"isBestSeller": false,
"review": {
"rate": 4.6,
"count": 129393
},
"imageId": "amiami_1"
},
"delivery": {
"deadLine": null,
"day": null,
"area": ""
}
},
: