iタウンページのスクレイピング:賢早くんの代わりになりたかった


背景

iタウンページの特定の情報を網羅的に取得するために、賢早くんというExcelマクロが配布されていたのですが、2019年11月のiタウンページ側の仕様変更により使用できなくなってしまいました。
そこで、スクレイピングの練習も兼ねて、Python初心者(大学の講義で少し触れた程度)が青息吐息でプログラミングに挑戦しました。
最終目標は「特定の小カテゴリーから店舗名・住所・カテゴリを取得する」です。

規約の確認

タウンページの規約ですが、以下の二点が禁止されています。
・iタウンページのサービスに多大な影響を与える行為
・自動的にアクセスするプログラムを使用してiタウンページに繰り返しアクセスする行為
https://itp.ne.jp/guide/web/notice/
今回は、ページの続きを読み込むためのボタンを最下まで押すだけというクソコードなので、繰り返しのアクセスではなく通常の利用の範疇ではないかと想定しています(これが不可なら通常利用でも最下までたどり着けない仕様……)。

環境

  • Windows10
  • Spyder3.3.6(Python3.7)
  • Selenium
  • Google Chrome 79

コード

Seleniumのインストール

Anaconda Prompt上で

pip install selenium

ドライバの指定・Chromeの起動

driver = webdriver.Chrome(executable_path='/Users/*****/*****/Selenium/chromedriver/chromedriver.exe')
driver.get('https://itp.ne.jp/genre/?area=13&genre=13&subgenre=177&sort=01&sbmap=false')

ドライバを指定した後,ブラウザで指定したURLを立ち上げます。
今回はパチンコ店を調べたので,エリア「東京都」,カテゴリ「屋内遊戯」で検索した場合のURLです。

最下行まで表示

while True:
    try:
        driver.find_element_by_class_name('m-read-more__text').click()
    except:
        print('☆「更に表示」連打終了☆')
        break

エラーを吐くまで(=最下行まで)「さらに表示」ボタンを連打します。
これでHTML上に,ヒットしたすべての店舗情報を表示します。

カテゴリー名を回収

elist = []
elems = driver.find_elements_by_class_name("m-article-card__header__category")
for e in elems:
     elist.append(e.text)
print(elist)

str_ = '\n'.join(elist)
print(str_)
with open("str_.txt",'w')as f:
    f.write(str_)

空のリストを作成して,Class名がm-article-card_header_categoryの要素のinnerTextをそこに放り込みます。
そののち,リストを1要素ずつ改行した文章にして,テキストで出力します。

終わり

flist = []
elems2 = driver.find_elements_by_class_name("m-article-card__header__title__link")
for f in elems2:
     flist.append(f.text)
print(flist)

str2_ = '\n'.join(flist)
print(str2_)
with open("str2_.txt",'w')as f:
    f.write(str2_)


glist = []
elems3 = elems2 = driver.find_elements_by_class_name("m-article-card__lead__caption")
for g in elems3:
     glist.append(g.text)
print(glist)

str3_ = '\n'.join(glist)
print(str3_)
with open("str3_.txt",'w')as f:
    f.write(str3_)


print('成功')
driver.quit()

タイトルとキャプション(住所・電話番号・最寄駅)についても,同じように出力します。
※キャプションはタイトルやカテゴリーと行数が違うので,Excelで整形しました。

詰まったところ

解決したところ

・forの後に:(コロン)を付け忘れる
・無限回繰り返す方法がわからない
→While True:でした。Trueが大文字始まりというところでも詰まりました
・ファイルに書き出す方法がわからない
→ファイル名を””で囲んでいなかったのが原因でした
・chromeDriverの場所の指定の仕方がわからない
→Chromedriverの入っているフォルダーまでしか指定していませんでした。当然Chromedriver.exeまで指定
・コマンドプロンプトでpip install seleniumを実行しても、Spyder上で実行できない
→Anaconda Prompt側で実行しないといけない
……他多数

未解決問題

・pipが何かわかっていない
・htmlの構造がわからない
→結局わからなかったのでSeleniumでブラウザを動かす形に
・【住所】の他に【電話番号】【最寄駅】がついてくる
→これが結構致命的で、おそらく本当は店舗1件をひとまとまりとして書き出した方がいいのでしょう(今回はExcelで処理しました)。本格的に必要になれば書き換える予定です

その他

・全国すべての店舗を表示するURLはhttps://itp.ne.jp/genre/
・東京都の店舗を表示するURLはhttps://itp.ne.jp/genre/?area=13

2019/12/20追記

カテゴリ,タイトル,住所それぞれで回収するでのはなく,class="o-result-article-list__item"で店舗ごとに回収したほうが整形しやすい事に気が付きました。