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

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

新規登録して質問してみよう
ただいま回答率
85.35%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

2457閲覧

スクレイピングで子要素内のテキストを取得できるようにしたい

tatsuya5.22

総合スコア8

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/09/11 01:18

編集2020/09/11 02:37

#BeautifulSoupを用いたスクレイピングにおいて子要素内のテキストを取得する方法はありますでしょうか?
下記にもありますが、次のHTML<div class="an ao ap aq ar">が親要素でありそれ以下のHTMLが子要素です。さらにその子要素の中の<div class="c5 f9 fa fb fc fd">の子要素であるのが<div class="fe ff fg fh">以降のクラスです。

しかし普段この子要素たち<div class="c5 f9 fa fb fc fd"><div class="fe ff fg fh">は親要素の中に隠れており、▶をクリックしないと出てこないようになっております。

HTML

1<div class="an ao ap aq ar"> 2 <div class="fp"></div> 3 <div class="c5 f9 fa fb fc fd"> 4 <div class="fe ff fg fh"> 5 <div class="fe ff fg fh"> 6 <div class="fe ff fg fh"> 7 <div class="fe ff fg fh"> 8 <div class="fe hi hj"> 9 <div class="af gc"> 10 <a tabindex="-1" href="https://www.ubereats.com/jp/kyoto/food-delivery/%E3%81%BB%E3%81%A3%E3%81%A8%E3%82%82%E3%81%A3%E3%81%A8-%E5%90%91%E6%97%A5%E5%88%87%E3%83%8E%E5%8F%A3/upB0SF_VQ3iBzQlQ3Ocs2w?pl=JTdCJTIyYWRkcmVzcyUyMiUzQSUyMiVFNSU5MCU5MSVFNiU5NyVBNSVFNSVCOCU4MiUyMiUyQyUyMnJlZmVyZW5jZSUyMiUzQSUyMkNoSUpMNlpKcGlZRUFXQVI1X0hOWFpWTDZYYyUyMiUyQyUyMnJlZmVyZW5jZVR5cGUlMjIlM0ElMjJnb29nbGVfcGxhY2VzJTIyJTJDJTIybGF0aXR1ZGUlMjIlM0EzNC45NDg3MDYxJTJDJTIybG9uZ2l0dWRlJTIyJTNBMTM1LjY5ODQxNzElN0Q%3D" 11 <figure height="240" class="gd af ge b3"> 12 <div class="cc el ag bp bq"> 13 <img alt="ほっともっと 向日切ノ口" src="https://duyt4h9nfnj50.cloudfront.net/resized/1543379091952-w550-59.jpg" aria-hidden="true" class="cc e1 hh cy"> 14 </div> 15 <div class="ag gf au cu cc gg aq"> 16 <button aria-label="お気に入りに保存" title="お気に入りに保存" class="b0 b9 gh af gi gj gk gl gm gn">...</button> 17 </div> 18 </figure> 19 <div class="gp au aw">...</div> 20 <div class="gw c3 c4 gx gy gz au aw">...</div> 21 </a> 22 </div> 23 </div> 24 <div class="fe hi hj"> 25 <div class="fe hi hj"> 26 <div class="fe hi hj"> 27 <div class="fe hi hj"> 28

自分がやりたいことは2つあります。

1つ目は<div class="fe hi hj">の中にある<img alt="ほっともっと 向日切ノ口">のテキストの部分("ほっともっと 向日切ノ口")を抜き出すことです。また同じクラス<div class="fe hi hj">が複数個あるので同様に全てのクラスからテキストを抜き出したいと思っております。

2つ目はcount関数を使い<div class="fe hi hj">がいくつあるかを求めることです。

Python

1page = requests.get("https://www.ubereats.com/jp/feed?pl=JTdCJTIyYWRkcmVzcyUyMiUzQSUyMiVFNSU5MCU5MSVFNiU5NyVBNSVFNSVCOCU4MiUyMiUyQyUyMnJlZmVyZW5jZSUyMiUzQSUyMkNoSUpMNlpKcGlZRUFXQVI1X0hOWFpWTDZYYyUyMiUyQyUyMnJlZmVyZW5jZVR5cGUlMjIlM0ElMjJnb29nbGVfcGxhY2VzJTIyJTJDJTIybGF0aXR1ZGUlMjIlM0EzNC45NDg3MDYxJTJDJTIybG9uZ2l0dWRlJTIyJTNBMTM1LjY5ODQxNzElN0Q%3D") 2soup = BeautifulSoup(page.content, 'lxml') 3 4menus = soup.find_all(class_="fe hi hj") 5menu_list = [menu.get_text() for menu in menus] 6 7print(menu_list)

上記の方法でテキストを入手しようとしましたが結果は[]でした。

これらをできる方法がありましたらご教授願います。

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

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

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

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

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

quickquip

2020/09/11 01:57 編集

> 上記の方法でテキストを入手しようとしましたが結果は[]でした。 再現できないのでsoupを作っているコード(あるいは質問用に再現するコード)を、質問を編集して追記してもらえますか?
Daregada

2020/09/11 01:39

HTMLファイルの構造がめちゃくちゃなのですが、元データからこうなんですか? ・最初のa要素の開始タグが閉じていない(>がない) ・最初のimg要素の開始タグが途中で閉じている(>が2つある) ・button要素の終了タグがない ・大量のdiv要素の終了タグがない
nto

2020/09/11 02:13 編集

そもそも「親要素の中に隠れており」という部分からも、今一度htmlに対する認識を改めた方が良いです。 あくまでもデベロッパーツール上で視認する事で"隠れている"様に見えるだけであり、別にhtmlの構造としては何ら隠れているものではありません。 デベロッパーツールではなくソースコードを直接確認すれば、何も要素は隠れておりませんし、▶を押さなければ見れない等といった事もありません。 また前回されている質もでも回答が出ておりますが、UberEatsの様な動的なサイトはBeautifulSoupだけでのスクレイピングは出来ません。seleniumを使用しましょう。
tatsuya5.22

2020/09/11 02:40

soupを作っているコード(あるいは質問用に再現するコード)追記致しましたのでもう一度確認してもらえると幸いです。
Daregada

2020/09/11 02:57 編集

requests.get()で取ってきたpage.contentをprintしてみればわかりますが、質問のHTMLに提示されているようなデータは取得できていませんよ。
quickquip

2020/09/11 02:57

page.text と質問に書いてあるhtmlがまったく違います。(指摘だけ) 「seleniumを使用しましょう」という情報をすでに得ているなら、他に回答できることはないなと思いました。(感想だけ)
Daregada

2020/09/11 02:59

まあ、もし取得できていたとしても(仮定: 実際にはできていない)、class_="fe hi hj"では複数クラスが指定された要素は取得できません。
tatsuya5.22

2020/09/11 03:08

これはUberEatsのウェブページ上でスクレイピングをしようと試みているのですが、実際のウェブページ上で検証をしHTMLを見てみると<div class="an ao ap aq ar">の子要素として自分が取得したいデータが存在します。しかし仰られた通り「requests.get()で取ってきたpage.contentをprint」をしても自分がほしいデータが取得できていない状態です。なぜこのような違いが生まれているのでしょうか?request.get()ではなく他の方法でHTMLを取得した方が良いのでしょうか?
quickquip

2020/09/11 03:30

> Daregada さん > class_="fe hi hj"では複数クラスが指定された要素は取得できません。 ここでする議論でもないですが、これは間違いで、質問に書いてあるhtmlだったら soup.find_all(class_="fe hi hj") で5件取得できます。 コードの問題ではない(soup.find_allは正しい)からこそ、回答できることがない=すでに過去に回答が出ている感じです。
tatsuya5.22

2020/09/11 03:42

みなさんご回答ありがとうございました。 コードどうこうの問題ではないこと。 UberEatsの様な動きがあるサイトはseleniumも使用してスクレイピングした方が良い。 理解いたしました。seleniumでのスクレイピングをトライしてみたいと思います。
Daregada

2020/09/11 04:07

> quickquipさん 失礼。class_="fe hi hj"だと、"fe hj hi"や"hj hi fe"といった、「クラスとしては同等だが、文字列は異なる」クラス指定をされた要素を取得できない、という話と混同していました。
guest

回答2

0

ベストアンサー

ブラウザ上でアクセスした際に、そこで初めてjavascript等で
ページ内のHTMLが生成されるといったサイトが多々あります。
これらを一般的には「動的」なサイトと称します。

従って、そういった動的なサイトのソースにはそれらのHTMLコードは記載されていません。
(上記の通り、アクセスした際に、そこで初めて店舗情報などのHTMLが生成される為)

簡易的に説明するとBeautifulSoupでは、内部的にhttpリクエストを送り
本来のソースコードを取得する事が出来るライブラリとなっていますが
動的なサイトでアクセス後に生成される様なソースは取得が出来ません。

反対にseleniumはpythonコードでブラウザを操作する事よって
動的なサイトでも店舗情報等のHTMLが生成された後にソースを取得する事が可能となっています。
seleniumを使用するにあたって何かご不明な点などがあった場合には改めてteratailでご質問下さい。

投稿2020/09/11 04:51

nto

総合スコア1438

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

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

tatsuya5.22

2020/09/11 05:23

ご丁寧にご回答していただきありがとうございます。 実はスクレイピングに関してはseleniumをあまり使用した経験がないため多少勉強してから取り掛かりたいと思います。 不明な点がありましたら再度質問させていただきたいと思います。
nto

2020/09/11 05:29

スクレイピングはいずれも割と直感的なコーディングが可能なものであり、また操作性もBeautifulSoupと似て非なるものではあるが近しいもので、BeautifulSoupを使用出来るのであればseleniumの使用もあまり難易度が高いものではないと思います。 頑張って下さい。
guest

0

提示されたHTMLファイルが静的に保存されているなら

Python

1from bs4 import BeautifulSoup 2 3soup = BeautifulSoup(open('hogehoge.html', encoding='UTF-8'), 'html.parser') 4 5for imgElement in soup.find_all('img'): 6 if ['fe', 'ff', 'fg', 'fh'] in [div['class'] for div in imgElement.find_parents('div')]: 7 print(imgElement['alt'])

でalt属性の値が取れます。

(なぜだかわかりませんが)class="fe ff fg fh"が指定されたdiv要素が4つ重なっているので、img要素を見つけて先祖を遡るように組みました。

投稿2020/09/11 02:33

Daregada

総合スコア11990

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問