質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1385閲覧

食べログの店舗一覧ページから、各店舗のURLを自動取得してそれぞれ解析したい

s61september

総合スコア5

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/09/03 15:03

編集2019/09/04 08:00

前提・実現したいこと

当方、プログラミング初心者です。

飲み会でビールの銘柄を指定されることが多いのですが、
食べログではビールの銘柄での絞り込みができません。

そこで、食べログをスクレイピングして、店舗一覧ページ(エリアで絞り込み後)の中から、
店舗説明テキスト内に希望のビール銘柄が含まれている店舗を抽出し、
店名と評価を表示するプログラムを組みたいと考えております。

該当のソースコード

※途中まで作成したものです↓

python

1import requests 2from bs4 import BeautifulSoup 3 4#店舗一覧ページに対するBeautifulSoupの設定 5list_url = 'https://tabelog.com/tokyo/A1302/' 6r_list = requests.get(list_url) 7html_list = r_list.content 8soup_list = BeautifulSoup(html_list, "html.parser") 9 10#店舗一覧ページ内のURLリンクの抽出 11for aa in soup_list.find_all("a"): 12 link = aa.get("href") 13 name = aa.get_text() 14 print(link,"\t",name) 15 16 17#個別店舗ページに対するBeautifulSoupの設定 18target_url = 'https://tabelog.com/tokyo/A1312/A131201/13234764/dtlmenu/drink/' 19r = requests.get(target_url) 20html = r.content 21soup = BeautifulSoup(html, "html.parser") 22 23#個別店舗の店名を抽出 24store_name = soup.find(class_="display-name").text 25#print(store_name) 26 27#個別店舗の評価を抽出 28rating_score_tag = soup.find('b', class_='c-rating__val') 29rating_score = rating_score_tag.span.string 30 31#個別店舗ページ内のテキストを全取得 32all_text=soup.find(all).text 33 34#テキスト内に希望ビール銘柄が含まれていたら店名と評価を表示する 35if "アサヒ" in all_text: 36 print(store_name+rating_score)

できていること

・店舗一覧ページ内に記載のあるURLを抽出すること
・個別店舗ページ内のテキストにビール銘柄が含まれていたら店名と評価を表示すること**

###できていないこと
①店舗一覧ページに記載のあるURLすべてを抽出してしまっている
→個別店舗のリンクURLのみを抽出したいができていない

②上記①で個別店舗のリンクURLのみを抽出できたとして、リスト化の仕方がわからない

③上記②のリストから順番にtarget_urlに代入を繰り返す処理をしたいができていない

###つまづいているポイント

①については、個別店舗URLは下記のようなクラス設定がされているため、
find_allの際にクラス指定をすればよいのかと思ったが、やり方がわからない。

<a class="list-rst__rst-name-target cpy-rst-name js-ranking-num" target="_blank" data-list-dest="item_top" data-ranking="1" href="https://tabelog.com/tokyo/A1302/A130204/13018162/">日本橋蛎殻町 すぎた</a>

③については、コードの"#個別店舗ページに対するBeautifulSoupの設定"以下を

python

1def check(target_url): 2#個別店舗ページに対するBeautifulSoupの設定 3target_url = 'https://tabelog.com/tokyo/A1312/A131201/13234764/dtlmenu/drink/' 4r = requests.get(target_url) 5html = r.content 6soup = BeautifulSoup(html, "html.parser") 7#個別店舗の店名を抽出 8store_name = soup.find(class_="display-name").text 9#print(store_name) 10#個別店舗の評価を抽出 11rating_score_tag = soup.find('b', class_='c-rating__val') 12rating_score = rating_score_tag.span.string 13#個別店舗ページ内のテキストを全取得 14all_text=soup.find(all).text 15#テキスト内に希望ビール銘柄が含まれていたら店名と評価を表示する 16if "アサヒ" in all_text: 17 print(store_name+rating_score)

などとして関数化し、for文でtarget_urlにリストから順番にURLを代入させる?
というような方法でしょうか?イメージがついておりません。

コメントを下さった方、ありがとうございます。
自分なりに改めて考えて追記致しました。
Markdown記法についてはわかっていない部分が多く申し訳ございません。

不足している情報などございましたらご指摘頂けましたら幸いです。
宜しくお願い致します。

###(追記)修正したプログラム

ご回答ありがとうございます。
頂いたアドバイスを参考に下記の通り修正したところ、うまく動きました。

python

1import requests 2from bs4 import BeautifulSoup 3import sys 4 5#ページネーション(次の20件)を変数 i で表現。今回は10ページ目まで取得している 6#i は数値(int)のため、URLに入れ込む際には文字列(str)に変換している 7#rangeは通常0から始まるするため、引数として1を追加して、1から始まるようにしている 8for i in range(1, 10): 9 #URLの"A1302"は「東京・日本橋」のディレクトリのため、他のエリアの場合は手打ちで変更必要 10 list_url = "https://tabelog.com/tokyo/A1302/rstLst/"+str(i)+"/?Srt=D&SrtT=rt&sort_mode=1" 11 12 #店舗一覧ページに対するBeautifulSoupの設定 13 r_list = requests.get(list_url) 14 html_list = r_list.content 15 soup_list = BeautifulSoup(html_list, "html.parser") 16 17 #店舗一覧ページ内の個別店舗ページURLの抽出 18 stores = soup_list.find_all(class_="list-rst__rst-name-target") 19 storeURLs = [ x['href'] for x in stores ] 20 21 #個別店舗のドリンクメニューページを集めたリストを作成 22 #個別店舗ページURLの末尾にドリンクメニューのディレクトリを追記したものをリストへ追加 23 drinkURLs = [] 24 for storeURL in storeURLs: 25 drinkURL = storeURL +"dtlmenu/drink/" 26 drinkURLs.append(drinkURL) 27 28 #各店舗のドリンクメニューページに希望のビール銘柄の記載があるか、リスト内URLを順番に確認 29 for target_url in drinkURLs: 30 31 #個別店舗ドリンクページに対するBeautifulSoupの設定 32 r = requests.get(target_url) 33 html = r.content 34 soup = BeautifulSoup(html, "html.parser") 35 36 #個別店舗の店名を抽出 37 store_name = soup.find(class_="display-name").text 38 39 #個別店舗の評価を抽出 40 rating_score_tag = soup.find('b', class_='c-rating__val') 41 rating_score = rating_score_tag.span.string 42 43 #個別店舗ドリンクページ内のテキストを全取得 44 all_text=soup.find(all).text 45 46 #テキスト内に希望ビール銘柄の記載があれば、店名と評価を表示する 47 #記載がなければ、その旨を表示する 48 if "キリン" in all_text: 49 print(store_name+rating_score) 50 else: 51 print(store_name+"キリンは置いていません") 52

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2019/09/04 00:38

①https://tabelog.com/tokyo/A1302/のレスポンスを取る ②店舗ページのリンクを抜き出してリストに納める。 ③②のリストからループを回してデータを抜き出す。 で、いいと思いますが、具体的にどの部分がわからないのか示せますか?
Y.H.

2019/09/04 00:38

「※途中まで作成したものです」に記載されているコードでは、やりたいことの、 ・なにができているのか ・何ができていないのか ・何が問題なのか(何につまづいているのか) を追記ください。
guest

回答1

0

ベストアンサー

①については、個別店舗URLは下記のようなクラス設定がされているため、find_allの際にクラス指定をすればよいのかと思ったが、やり方がわからない。

find_allの際にクラス指定をすればよい

まさにそのとおりです。

python

1stores = soup.find_all(class_="list-rst__rst-name-target")

②上記①で個別店舗のリンクURLのみを抽出できたとして、リスト化の仕方がわからない

内包表記を使えばいいかと思います。

python

1storeURLs = [ x['href'] for x in stores ]

③...for文でtarget_urlにリストから順番にURLを代入させる?というような方法でしょうか?

まさにそのとおりです。

python

1for target_url in storeURLs:

投稿2019/09/04 03:33

Lhankor_Mhy

総合スコア36074

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s61september

2019/09/04 08:05

ありがとうございます。おかげさまでうまく動きました。 内包表記は初めて知りました。 x['href']で、storesに含まれるリンクURL箇所のみを抜粋してリストに追加することができるのですね。 大変勉強になりました。ありがとうございます。
Lhankor_Mhy

2019/09/04 08:15

ご解決されて何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問