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

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

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

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

Python 3.x

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

Q&A

解決済

2回答

32378閲覧

BeautifulSoup4のfind_allでタグの中の文章が取得できない

hhhhhhhhh

総合スコア13

Beautiful Soup

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

Python 3.x

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

0グッド

0クリップ

投稿2018/12/20 15:44

前提・実現したいこと

<strong style="color:#C84B00;font-size: 16px;"></strong>
<strong style="color:#C84B00;font-size: 16px;"></strong>
上記で言う「犬」「猫」のような
複数の要素を持つタグに含まれている、内容だけを取得したいです。※idやclassがありません。
(本来はこちらのソースを取得しています)

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

複数の該当する内容を取得したいので.find_all()を利用しています。
詳細は該当のソースコードに記載しています。

"ResultSet object has no attribute '%s'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?" % key AttributeError: ResultSet object has no attribute 'text'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()? Exited with status 1 after 0.26 seconds

該当のソースコード

python3

1import urllib.request 2from bs4 import BeautifulSoup 3html = urllib.request.urlopen("http://yume-uranai.jp/keyword.php?keyword=%8C%A2&q=1") 4soup = BeautifulSoup(html, "html.parser") 5title = soup.find_all("strong",style="color:#C84B00;font-size: 16px;") 6print(title.text) 7

調べたこと

この質問では、.stringの位置が違うんじゃないか?と言う回答が寄せられていました。
.stringは、.textと違い、1つの要素の時に使うものだと認識しております。
こちらを読みましたが、まだよく理解していません。とりあえず、.textが大味な意味で使える物と言う認識もしています。
質問を参考に.textの位置を変えて見ました。

title = soup.find_all("strong",style="color:#C84B00;font-size: 16px;".text) print(title)

もしくはこちらも

title = soup.find_all("strong",style="color:#C84B00;font-size: 16px;").text print(title)

どちらとも最初と同じエラーメッセージが出ます。

しかし、print(title)を使わずに、このようにforで1つずつ取り出すと正しく中身だけを抜くことができました。

for i in title: print(i.text)

以下の参考にした記事全て、このようなfor文での書き方はしていません。
https://qiita.com/itkr/items/513318a9b5b92bd56185
https://qiita.com/connectcrew-ishii/items/6ad316ea854326c536a6
http://python.zombie-hunting-club.com/entry/2017/11/08/192731

僕の調べ方が悪いのか、また分からなさすぎて理解が足りていないだけなのか、恐らくその両方だと思いますが
forを使わずに、find_allで文章だけ取得することは不可能なのでしょうか?
僕はこの結果を配列に格納したいのですが、せっかくfind_allで取得した、タグも含まれている配列をfor文で出力し
また別の配列に入れなければなりません。
最初から、find_allで中身だけ取り出せれば良い物だと思うのですが、全くやり方がわかりません。

右も左も分からないレベルに初心者なので、エンジニアの方が想定している考え方が全くできていないと思いますが、ご回答していただければ幸いです。

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

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

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

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

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

guest

回答2

0

find_all(), find() に text 引数を指定することで、指定した値を持つ要素を検索できます。
この指定には正規表現が利用できるので、次のようにしてみてはどうでしょうか。

python

1import re 2import urllib.request 3from bs4 import BeautifulSoup 4 5url = 'http://yume-uranai.jp/keyword.php?keyword=%8C%A2&q=1' 6html = urllib.request.urlopen(url) 7soup = BeautifulSoup(html, 'html.parser') 8 9# 要素名が strong で値に犬または猫を含む要素を抽出 10elems = soup.find_all('strong', text=re.compile('(犬|猫)')) 11 12# 結果 13for elem in elems: 14 print(elem.string)
犬 子犬 犬に噛まれる 犬を飼う 犬と散歩する 大型犬 犬に吠えられる 犬と遊ぶ 犬を躾ける 愛犬

投稿2018/12/20 16:23

tiitoi

総合スコア21956

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

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

0

ベストアンサー

find_allは複数の要素を返すので、forループを使うしかありません。
.stringでも.textでも関係ありません。
提示URLhttps://qiita.com/connectcrew-ishii/items/6ad316ea854326c536a6でも、(selectで要素を取得していますが)実際のtextを取得するさいはforループを利用しています。

forを使わずに、find_allで文章だけ取得することは不可能なのでしょうか?

僕はこの結果を配列に格納したいのですが、せっかくfind_allで取得した、タグも含まれている配列をfor文で出力し
また別の配列に入れなければなりません。
最初から、find_allで中身だけ取り出せれば良い物だと思うのですが、全くやり方がわかりません。

以下でよいのではないでしょうか?

Python

1# 略 2ret = [] 3for t in title: 4 ret.append(t.text) 5#ret = [t.text for t in title] # これでもよい 6 7print(ret) # ['犬', '子犬', ~]

投稿2018/12/20 16:06

can110

総合スコア38262

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

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

hhhhhhhhh

2018/12/24 08:25

ご回答ありがとうございます。 タグから取得する際に正規表現よりユニークなタグを指定しており、内包表記の実用性が高いため、こちらをベストアンサーにさせていただきました。tiitoiさんもご回答ありがうございました。正規表現についてももっと勉強してみたいと思います。 以下のコメントは回答義務はありません。 初学者なのでよく詰まり自力で解決できず、諦めることの多い僕の疑問です。お時間のある際、気が向いた時などにお答え頂ければすごく嬉しいです。(書いて頂かなくても構いません。) 今回の質問は大方自分の中で解決した後に疑問点を質問していたので、コードの完成自体はなんとかなったのですが 本当に何が何だか分からない場合はみなさんどうしていますか? 今回bs4として質問致しましたが、本来私はseleniumで情報を取得して来ようと思っていました。 しかし、要素の取得がうまくいかずbs4にソース丸投げで対応するという結果になりました。(恐らくこの対応は今後seleniumの操作で泣きを見そうです) また、その逃げた先のbs4でもこの通り、qiitaの記事を読んでも理解できず...と言う結果でした。 僕は大抵、質問する以前に「どこが分からないのかすら分からない」と言う状態になっています。 恐らくそう言う時は人に現在知っていることや詰まっている状態をそのまま見せて相談すると思うのですが、孤独にコーディングしている為、そう言う友達がいません... 検索も未知には対応していないので、検索をしても知っていることしか分かりませんでした。 テラテイルは「15分調べても分からないことは、質問しよう!」とのことですが、恐らくその状態の質問内容は稚拙すぎて苦情が出ます。それが怖くて今まで質問できませんでした。 大方経験者からは、調べれば分かるだろ!と思う内容について、僕も質問しているのではないかと思っています。 なるべく自力で解決するために、みなさんがどの様にして未知の問題について対応しているのかご教授いただければ幸いです。 基本的なpythonの扱いはできているかな?と思っているので、主にライブラリやフレームワークなどの勉強方法について教えていただければ幸いです。
can110

2018/12/24 11:17

「どこが分からないのかすら分からない」状態では質問はしないほうがよいと考えています。 以下、私が実践してきた方法です。 まず、そのような状態の場合、もっと簡単な問題から取り組むようにしてきました。 また、いきなりやりたいことをコーディングしようとするのではなく、入門書や公式のマニュアル、チュートリアルを**分かるまで繰り返し繰り返し繰り返し…**やってきました。 簡単な問題から、徐々にやりたいことへ近づいていく感じです。 なお、質問者様の疑問、質問は私も含め多くの初心者が通ってきた道なので、新たに別途質問を立てると 多くの人から有益なアドバイスなり類似の過去質問を紹介してもらえる可能性があります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問