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

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

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

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

Q&A

解決済

3回答

20120閲覧

BeautifulSoupで特定div内の複数のタグの要素を取得する方法

horik

総合スコア44

Python 3.x

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

1グッド

1クリップ

投稿2016/05/26 14:20

編集2016/05/29 12:44

attakeiさん再び回答ありがとうございます。
だいぶスッキリとコードが書けるようになりました。

addressのdictのkeyの部分;
address.append({li.attrs.get('class')[0]: li.text})

はもっと綺麗に書く方法はないでしょうか?
liのclassを取得したいだけなのに
attrs.get('class')[0]
こういうのしか思い当たりませんでした。

これが最善であれば、このままベストアンサーにさせていただきます。

python

1profile = [] 2soup = BeautifulSoup(html, "html.parser") 3 4for div in soup.select(".profile"): 5 name = div.h3.text 6 hobby = [] 7 address = [] 8 for a in div.select('ul.hobby > li > a'): 9 hobby.append(a.text) 10 for li in div.select('ul.address > li'): 11 address.append({li.attrs.get('class')[0]: li.text}) 12 profile.append({"name": name, "hobby": hobby, "address": address}) 13 14print(profile)

python

1[ 2{'name': '山田太郎', 'hobby': ['サッカー', 'ドライブ'], 'address': [{'city': '東京都'}, {'ward': '新宿区'}, {'town': '西新宿'}]}, 3{'name': '鈴木花子', 'hobby': ['手芸', '料理', '旅行'], 'address': [{'city': '大阪市'}, {'ward': '中央区'}]} 4]

attakeiさん回答ありがとうございます。
追加で質問させてください。

ul要素が複数あった場合、最初の要素は取れましたが、
二つ目以降の取り方がわかりませんでした。

下のコードで取れたデータ:
[{'name': '山田太郎', 'hobby': ['サッカー', 'ドライブ']},
{'name': '鈴木花子', 'hobby': ['手芸', '料理', '旅行']}]

期待する出力は:
[{'name': '山田太郎', 'hobby': ['サッカー', 'ドライブ'], 'address': [{'city': "東京都"}, {'ward': "新宿区"}, {'town': "西新宿"}]},
{'name': '鈴木花子', 'hobby': ['手芸', '料理', '旅行'], 'address': [{'city': "大阪市',}, {'ward': '中央区'}]}]


html = """

<div class="profile"> <h3>山田太郎</h3> <ul class="hobby"> <li><a href="#">サッカー</a></li> <li><a href="#">ドライブ</a></li> </ul> <ul class="address"> <li class="city">東京都</li> <li class="ward">新宿区</li> <li class="town">西新宿</li> </ul> </div> <div class="profile"> <h3>鈴木花子</h3> <ul class="hobby"> <li><a href="#">手芸</a></li> <li><a href="#">料理</a></li> <li><a href="#">旅行</a></li> </ul> <ul class="address"> <li class="city">大阪市</li> <li class="ward">中央区</li> </ul> </div> """ profile = [] soup = BeautifulSoup(html, "html.parser") for div in soup.select(".profile"): name = div.h3.text hobby = [] for a in div.ul.findChildren("a"): hobby.append(a.text) profile.append({"name": name, "hobby": hobby}) print(profile)

==============前回の質問==============
例えば下のようなHTMLがあっとして、二人のプロフィールを次のようなjson形式で保存したいと考えています。
{[name: "山田太郎", comment: "よろしくお願いします", age: 26, address: "東京都"], [name: "鈴木花子", comment: "よろしくお願いします", age: 20, address: "大阪府"]}

html = """

<div class="profile"> <h3>山田太郎<h3> <p>よろしくおねがいします</p> <ul> <li>26歳</li> <li>東京都</li> </ul> </div> <div class="profile"> <h3>鈴木花子<h3> <p>よろしくおねがいします</p> <ul> <li>20歳</li> <li>大阪府</li> </ul> </div> """ soup = BeautifulSoup(html, "html.parser")

試したこと:
for name in soup.select(".profile > h3")
print(name.text)
こうすると山田太郎と山田花子の名前を取れますが、
あとの年齢、都道府県を名前と紐付けた形で取得できません。

なにかいい方法はありませんでしょうか?

idkohhi👍を押しています

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

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

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

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

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

argius

2016/05/27 16:41 編集

って、既にattakeiさんが書いてましたね 余計なことをしてしまったすみません > 良く見たら<h3>の閉じタグが閉じられていませんね。</h3>でなくて<h3>になっています。
argius

2016/05/27 16:25

おっと、回答したのは私ではないですよ。
guest

回答3

0

※2番目に追加された方の質問に対する回答です。

大まかに書くと、selectで抽出可能です

自分も普段からそこまで深く使っているわけではないですが、「BeaufulSoupで抽出した要素は、さらにselectなどのメソッドが使用可能」という感じでいてもらえればいいかと。

Python

1soup = BeautifulSoup(html, "html.parser") 2profile = [] 3for div in soup.select(".profile"): 4 name = div.h3.text 5 hobby = [] 6 for a in div.select('ul.hobby > li > a'): 7 hobby.append(a.text) 8 address = [] 9 for li in div.select("ul.address > li"): 10 address.append(li.text) 11 profile.append({"name": name, "hobby": hobby, "address": address}) 12 13print(profile)

こんな感じでしょうか

投稿2016/05/29 12:03

attakei

総合スコア2738

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

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

0

提示されていたhtmlだとh3タグが閉じられていないのですが、閉じられている想定で書いてみます。

この場合だと、名前があるh3タグのみで抽出すると面倒なので、ひとくくりになっている.profileクラスのdivタグを1セットにしてループさせた方がいいかと思います。

python

1for profile in soup.select('.profile'): 2 # 名前 3 print(profile.h3.text) 4 # コメント 5 print(profile.p.text) 6 # 年齢 7 print(profile.ul.findChildren()[0].text) 8 # 住所 9 print(profile.ul.findChildren()[1].text)

HTMLの構造が上記の内容なら、これで各タグの中身のテキストはprint出力できます。

投稿2016/05/27 03:23

attakei

総合スコア2738

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

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

0

ベストアンサー

※あまり、一つの質問記事に次々と質問が足されていくのは良くないかな、と思いながら勉強がてら調べてみました

ドキュメントを読む限りだと、タグ要素にひもづいている属性は辞書として取り出せるみたいですね。

python

1li.attrs.get('class')[0]

python

1li['class'][0]

これで取れるみたいです。

投稿2016/05/30 15:08

attakei

総合スコア2738

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

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

horik

2016/05/31 01:45

ありがとうございます。 以後気をつけます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問