0
0

グーバイクに販売中のバイク一覧をスクレイピングしてみた

Last updated at Posted at 2024-06-14

流石に業務時間内で堂々とバイク販売サイトを見るのもあれですが、
仕事中の暇な時間を利用して、グーバイクに販売中のバイク一覧をスクレイピングしてみたよ。

今回の流れについて解説しましょう。

なぜスクレイピング?

暇だから:joy:
主な原因は、KTM 390 Duke から 890 SMT に乗り換えようと考えています。

そのため、いつもサイトを見るより、コーディング画面のほうが上司から指摘されないから
(小声)

まず調査を行おう

グーバイク側では、データベースから抽出された結果を動的にフロント側で同じdiv構成によってloopしてレンダリングするはずです

(多分。。。。)

image.png
パッと見たら、確かに一台ずつ同じbike_secとの class のdivで構成されていますね。

なので今回は、Python のBeautifulSoupモジュールのfind()またはfind_all()を利用して、特定divの内容を抽出すればいいですよ。

画面構成

詳しく調査した結果、基本的に一台のバイクに対して、<div class="bike_sec"><div class="shop_info>という2個のdiv要素が付与されていることが分かりました。

bike_secはバイク情報、shop_infoは販売店情報になっております。

<div class="bike_sec">                  検索結果
    <div class="clear_fix">
        <div class="bike_img">          画像
        <div class="bike_info">         車体情報
            <div class="model_title">   モデル
            <div class="fav_btn">       検討ボタン
            <div class="detail_cont">   車体情報エリア
                <div class="cont01">
                    <table>             車両価格 + 支払総額
                    <ul>
                        <li> 0番
                            <span>      モデル年式
                            <b>         年式数字 + 年
                            
                        <li> 1番
                            <span>      初度登録年
                            <b>         新車(在庫あり)/ 年式数字 + 年
                            
                        <li> 2番
                            <span>      走行距離
                            <b>         ― / 距離数字 + Km
                            
                        <li> 3番
                            <span>      車検/自賠責保険
                            <b>         検 + yyyy/mm
                            
                        <li> 4番
                            <span>      修復歴
                            <b>        (不明)
                                        * 修復歴のあるバイク見かけたことない
                <div class="cont02">

    <div class="shop_info>
        <div class="bxl>
            <div class="shop_name">     販売店名前
                <dt>                    店名
                <dd>                    場所 + 営業時間
            <div class="cus_voice">     販売店へのお客様の声

実際の画面は以下のようになります。
image.png
image.png

メインに調べたい情報は、<li>の0番目から3番目の

値段年式初度登録年走行距離車検店名(場所)です。

また、グーバイクの画面ではデフォルトで50個の結果しか表示しないため、ソース上で画面のページネーションの統計文から、最大ページ数を取得し、for文で繰り返します。
image.png

image.png

なので、bxr class の<p>要素の全{num}ページの数値を抽出すればいいです。

使用例

$ python goobike_scraper.py
メーカー: ktm
モデル名: 390_duke
年式を指定するか (y/n): y
年式: 2020
支払総額を昇順で表示するか (y/n): y

メーカー名とモデル名を入力した後、スクレイピングが始めます。
その後、年式を指定するか、または昇順で表示かを聞いてくれます。

出力例

47万円, 2020年, 2021年, 14245Km, 検2026/01, C204 (大阪府守口市佐太中町3丁目9−16ドミール佐太1F)
47万円, 2020年, 2021年, 17380Km, 検2024/08, バイク王 伊丹店 (兵庫県伊丹市北伊丹5−96−1)
47万円, 2020年, 2021年, 14245Km, 検2026/01, C204 (大阪府守口市佐太中町3丁目9−16ドミール佐太1F)
47万円, 2020年, 2021年, 17380Km, 検2024/08, バイク王 伊丹店 (兵庫県伊丹市北伊丹5−96−1)
49万円, 2020年, 2020年, 19239Km, 検無し, バイク館富田林店 (大阪府富田林市喜志町5丁目4−30)
50万円, 2020年, 2020年, 17565Km, 検2025/06, KTM小山 (栃木県小山市雨ケ谷新田69−1)
51万円, 2020年, 2020年, 7422Km, 検無し, ビジョギマンケーブ (埼玉県戸田市美女木4−19−27)
51万円, 2020年, 2021年, 2131Km, 検無し, バイクランド直販センター 環七鹿浜店 (東京都足立区椿2−2−2)

割と綺麗に抽出していますね。

分かったこと

グーバイク側では検索用APIが公開されていないため、あくまでもユーザー側がアクセスできる画面に対した調査結果となります。

また、コマンド引数のメーカーモデル名によって自由に調べられるよう色々実装しましたが、なぜかグーバイク側で生成された固定URLが 規則的ではない と分かりました。

不規則なURL

最初に実装するとき、URLのパラメータは全部

www.goobike.com/maker-{manufacturer}/car-{manufacturer}_{model}/index{page_number}.html

との解釈で大丈夫かと思いましたが、実際に一部のモデル名がアンダーバー付いてたり、付いていなかったりしています。

たまに

maker-{manufacturer}/car-{model}/index.html

の場合もありますが...

以下は例です

https://www.goobike.com/maker-ktm/car-ktm_890smt/index.html
https://www.goobike.com/maker-ktm/car-ktm_890duke_r/index.html
https://www.goobike.com/maker-ktm/car-ktm_390_adventure/index.html
https://www.goobike.com/maker-bmw/car-bmw_f900xr/index.html
https://www.goobike.com/maker-honda/car-honda_cbr250rr/index2.html

外車

まず大好きな KTM のほうから、Dukeシリーズの場合でも
390_duke 890duke 890duke_r 1290_super_duke_r
のようなめちゃくちゃなネーミングルール、何なんだよ。

アドベンチャーシリーズの場合は結構いいです。
790_adventure 890_adventure_r 1290_super_adventure_s

他の外車勢も割とマシだろうと。
BMW は f900xr r1250gs_adventure、MVアグスタは f3_800

日本車

次に日本車の場合、

Honda は cbr250rr crf1000l_africa_twin、Yamaha は yzf-r6

統一しろよおい(怒)

単に {num}_{seriesModel} では無理のようです。

修正するなら?

外車の場合、改めてグーバイク側で表示するモデル名の辞書を用意して、アンダーなどを付くか付かないかを変換します。

日本車の場合、URLパラメータは maker-{manufacturer}/car-{model}/ で解釈できそうな感じなので、if文で4大メーカーの場合だけURLを書き換えれば実現できるかと思います。

今後の課題

  1. 抽出結果をSQLに保存して、新規追加した分のみ提示するように修正すること
  2. モデル色は今回判別できていないため、画像認識とかを実装して、更にモデル色が分かるようにすること
  3. 今回は類似csv形式で抽出したため、今度はjson形式で出力し、上記のモデル色など要素も追加し、結果分析を容易にすること
  4. モデル名の入力規則を追加・修正する
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0