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

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

新規登録して質問してみよう
ただいま回答率
85.30%
Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

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

Q&A

解決済

1回答

1114閲覧

python スクレイピング 取得できないclassがある場合

T5-8

総合スコア1

Beautiful Soup

Beautiful Soupは、Pythonのライブラリの一つ。スクレイピングに特化しています。HTMLデータの構文の解析を行うために、HTMLタグ/CSSのセレクタで抽出する部分を指定することが可能です。

Python

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

0グッド

0クリップ

投稿2023/02/12 05:33

実現したいこと

スクレイピングをしてHTMLまで取得したのですが、取得したいclassが見つからずに困っております。
スクレイピング内容はmakuakeの歴代売上ランキングのデータを所得したいと考えております。

見つからないclass <div data-v-0388f8bt data-v-f5afbcb6 id='wrapper'> ==$0 <div data-v-0388f8bt class="discover-contents">...</div>

のclass="discover-contents"です。

現在の入力コード

import requests from bs4 import BeautifulSoup url = "https://www.makuake.com/discover/most-funded" res = requests.get(url) soup = BeautifulSoup(res.text, "html.parser") classA = soup.find_all(attrs{'class': 'discover-contents'})

発生している問題・エラーメッセージ

classA

実行結果 [ ]

res.textの段階でcommand+F で検索しても取得したいclassが見つかっておりません。

お手数をおかけしますが、別の取得方法などご教授頂ければなと思っております。
よろしくお願いいたします。

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

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

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

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

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

melian

2023/02/12 06:03

対象のウェブページの HTML ソースコードを見ますと、以下の様な JavaScript コードの読み込み部分があります。 <script src="//d1h20jgietq515.cloudfront.net/340cfb142f9723fffc3739cbb3269c0a43716861/vue/js/pc/discover/most-funded.js"></script> この most-funded.js 内で discover-contents の値が挿入されています。 ... r("div",{staticClass:"discover-contents"},[r("discover-header",[r("template",{slot:"title"}, ... なので、Selenium を利用する方がよいかと思います。
T5-8

2023/02/12 07:02

コメントありがとうございます。 from selenium import webdriver # Chromeブラウザを起動(ChromeDriverのパスを指定) driver = webdriver.Chrome(executable_path="/path/to/chromedriver") seleniumは難しくパスの指定をしてもうまくできませんでした。 現在Chromのバージョンの同じものをダウンローと現在のディレクトリを確認しましたが同じく以下エラーが出てしました。 WebDriverException: Message: '<chromedriver>' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home ターミナルなどでchromedriverをインストール brew install chromedriver こちらも試しましたがいまいちできませんでした。 長くなり申し訳ございません。
melian

2023/02/12 07:05

そうでしたら、Demerara さんの回答にある、「APIを利用する」を試してみるとよいかと思います。
T5-8

2023/02/12 07:07

かしこまりました。 ご丁寧にありがとうございます。 APIの方を調べてみます。 ありがとうございました。
guest

回答1

0

ベストアンサー

該当のページは、javascript によって動的にページの内容を変化させています。
このようなページの場合、ページのロードを待つ必要があります。しかし、requests に代表されるリクエスト方法では、javascript 適用前のまっさらな状態の HTML しか取得できません。

解決策はいくつかあります。

API を利用する

この場合、まず始めにすることは開発者ツールのネットワークタブを開いて、どのような通信が行われているかを確認します。もしここに、json データを返す API 等の URL があれば、それのレスポンスを確認します。幸い、今回はそれが見つかりました。

https://api.makuake.com/v2/projects?page=1&per_page=15&type=most-funded

レスポンスの中身は質問者さんが欲しがってる内容です。この URL にリクエストを投げて、返ってきたレスポンスを res.json() として、辞書型に変換します。あとは、辞書を操作する方法で任意の中身を取り出すだけです。

HTML を解析する

ネットワークタブでこのような URL が見つからなかった場合は、HTML そのものに json が埋め込まれているパターンがあります。

まず、script タグを探します。次に、その属性が application/json であるものがないか探します。もし、あればその要素を取得して、json.load() を利用して辞書型に変換して任意の中身を取り出します。

ブラウザ自動操作

どちらの方法でも取得できない場合、ブラウザ自動操作ツールの出番です。seleniumplaywright 等を使って要素が出現するまでページのロードを待機します。

selenium なら、driver.implicitly_wait(10) のように待機時間を設定します。
playwright なら、非同期で await するだけです。

投稿2023/02/12 06:18

Demerara

総合スコア397

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

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

Demerara

2023/02/12 07:24

はい、URL は 1. 開発者ツールを開く 2. ネットワークタブを選ぶ 3. XHR を選択 4. Type が json になっているものを見つける。または、URL に api が含まれるものを探す の手順で探しました。 URL のパラメーターでページ数が指定できます。page=1 の部分です。 たとえば、ページ数が 10 なら、 for page in range(1, 10): url = f"https://api.makuake.com/v2/projects?page={page}&per_page=15&type=most-funded" requests.get(url) とすれば、複数のページに順番にリクエストを送信できます。
T5-8

2023/02/12 07:29

ありがとうございます。 確認できました、誠にありがとうございます。
Demerara

2023/02/12 07:34

ちなみに、パラメーターの per_page=15 の 15 の値を変更すると、表示されるアイテムの最大数を変更できます。最大値は 100 でした。101 で試すと 400 エラーが変えてってきました。 アイテムの総数は API によると 188000 件なので、100 件ずつ取得すれば、全ページの取得は 188 ページで済む計算になります。
T5-8

2023/02/12 07:49

丁寧にありがとうございます。 お陰様でで色々調べそうです。 誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問