Pythonのスクレイピングコードについてアドバイス下さい
Q&A
解決したいこと
個人のプログラミング学習に使用します。
Pythonで食べログからお店情報を抽出し、CSVに落とし込むというコードを作成しました。
実行結果は思った通りになったのですが、かなり長ったらしいコードになり、本当にこのコードが最適解なのか?と思いご質問させて頂きました。
「for文で回し、1つずつ辞書に格納する」というフェーズは崩したくありません。(それ以外の知識がないため)
それ以外で、if文のところなどが自己流で作成したので、正しいか不安です。
エラーというより、添削のご依頼に近いかもしれませんが、ご教示頂けますと幸いです。
発生している問題・エラー
特になし
該当するソースコード
import requests
from bs4 import BeautifulSoup
from time import sleep
from pprint import pprint
import pandas as pd
import re
import time
# 時間計測開始
time_sta = time.perf_counter()
#URlとHTMLデータ取得
url = "https://tabelog.com/hokkaido/C1100/rstLst/{}/?Srt=D&SrtT=rt&sort_mode=1&svd=20230717&svt=1900&svps=2"
d_list = []
for i in range(1,61):
target_url = url.format(i)
r = requests.get(target_url)
soup = BeautifulSoup(r.text,"html.parser")
sleep(1)
#ページから店舗一覧取得
shops = soup.find_all("div",class_="list-rst__wrap js-open-new-window"
#一つ目の店舗情報を元に、全ての店舗情報を取得 ←気になっている部分
for shop in shops:
if float(shop.find("span",class_="c-rating__val").text) >= 3.5:
if shop.find("div",class_="list-rst__pr") and shop.find("span",class_="list-rst__holiday-text"):
name = shop.find("a",class_="list-rst__rst-name-target").text
acsess = shop.find("div",class_="list-rst__area-genre").text.strip()
strengths = shop.find("div",class_="list-rst__pr").text.strip()
evaluation = shop.find("span",class_="c-rating__val").text
reviews = shop.find("em",class_="list-rst__rvw-count-num").text
bookmark = shop.find("span",class_="list-rst__save-count-num").text
holiday = shop.find("span",class_="list-rst__holiday-text").text
money = shop.find("span",class_="c-rating-v3__val").text
row_url = shop.select("a")[0].get("href")
d = {"店舗名":name,"アクセス/ジャンル":acsess,"アピールポイント":strengths,
"評価":evaluation,"口コミ数":reviews,"お気に入り数":bookmark,"定休日":holiday,
"予算":money,"URL":row_url}
elif shop.find("div",class_="list-rst__pr"):
name = shop.find("a",class_="list-rst__rst-name-target").text
acsess = shop.find("div",class_="list-rst__area-genre").text.strip()
strengths = shop.find("div",class_="list-rst__pr").text.strip()
evaluation = shop.find("span",class_="c-rating__val").text
reviews = shop.find("em",class_="list-rst__rvw-count-num").text
bookmark = shop.find("span",class_="list-rst__save-count-num").text
holiday = "記載なし"
money = shop.find("span",class_="c-rating-v3__val").text
row_url = shop.select("a")[0].get("href")
d = {"店舗名":name,"アクセス/ジャンル":acsess,"アピールポイント":strengths,
"評価":evaluation,"口コミ数":reviews,"お気に入り数":bookmark,"定休日":holiday,
"予算":money,"URL":row_url}
elif shop.find("span",class_="list-rst__holiday-text"):
name = shop.find("a",class_="list-rst__rst-name-target").text
acsess = shop.find("div",class_="list-rst__area-genre").text.strip()
strengths = "記載なし"
evaluation = shop.find("span",class_="c-rating__val").text
reviews = shop.find("em",class_="list-rst__rvw-count-num").text
bookmark = shop.find("span",class_="list-rst__save-count-num").text
holiday = shop.find("span",class_="list-rst__holiday-text").text
money = shop.find("span",class_="c-rating-v3__val").text
row_url = shop.select("a")[0].get("href")
d = {"店舗名":name,"アクセス/ジャンル":acsess,"アピールポイント":strengths,
"評価":evaluation,"口コミ数":reviews,"お気に入り数":bookmark,"定休日":holiday,
"予算":money,"URL":row_url}
else:
name = shop.find("a",class_="list-rst__rst-name-target").text
acsess = shop.find("div",class_="list-rst__area-genre").text.strip()
strengths = "記載なし"
evaluation = shop.find("span",class_="c-rating__val").text
reviews = shop.find("em",class_="list-rst__rvw-count-num").text
bookmark = shop.find("span",class_="list-rst__save-count-num").text
holiday = "記載なし"
money = shop.find("span",class_="c-rating-v3__val").text
row_url = shop.select("a")[0].get("href")
d = {"店舗名":name,"アクセス/ジャンル":acsess,"アピールポイント":strengths,
"評価":evaluation,"口コミ数":reviews,"お気に入り数":bookmark,"定休日":holiday,
"予算":money,"URL":row_url}
d_list.append(d)
else:
continue
#CSVファイルに変換
df = pd.DataFrame(d_list)
df2 = df.applymap(lambda x: re.sub('\n', '', x))
df2.to_csv("食べログ高評価.csv",index=None,encoding="utf-8-sig")
# 時間計測終了
time_end = time.perf_counter()
# 経過時間(秒)
tim = time_end- time_sta
print(tim)
自分で試したこと
全体でif文による条件分岐をせずに表示しようとも考え、
if shop.find("div",class_="list-rst__pr"):
strengths = shop.find("div",class_="list-rst__pr").text.strip()
else:
notype = "記載なし"
のような形にし、辞書内でも"アピールポイント":strengths or notype
のようにしましたが、正しくCSVに出力されませんでした。