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

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

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

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

Q&A

解決済

2回答

412閲覧

同じ要素の異なる階層のスクレイプについて

idkohhi

総合スコア15

Python

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

0グッド

0クリップ

投稿2022/07/14 09:28

HTMLで、最初の階層のdiv要素のclassが"aaa"のものが2つあり、
1つの"aaa"のはさらに下の階層に"bbb"のclassがあります。
"aaa"classのものをダブって取ってきてしまうので、求めている結果もダブってしまいます。

具体的には以下のようなHTMLとpythonのプログラムとその結果です。

HTML

<html> <head> <meta charset="UTF-8"> <titlet></title> </head> <body> <div class="aaa"> <div class="bbb"> <a href="test01.html">test01です</a>? </div> </div> <div class="aaa"> <a href="test02.html">test02です</a> </div> </body> </html>

python

import requests from bs4 import BeautifulSoup load_url = 'http://localhost/python/test_tera06.html' html = requests.get(load_url) soup = BeautifulSoup(html.content, "html.parser") print(html.status_code) for link_01 in soup.find_all('div', class_= 'bbb'): print(link_01.text) for link_02 in soup.find_all('div', class_= 'aaa'): print(link_02.text)

実行結果

test01です
test01です
test02です
*改行は取り除いています。

やりたいこと

test01です
test02です

としたいのですが、どうすればいいのでしょうか。

Classのfind_allでのand条件ができれば、
例:find_all('div',class_'aaa,bbb')のような指定
と思ったのですが、わかりません。

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

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

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

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

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

guest

回答2

0

ベストアンサー

やりたいことが質問に明記されていませんが、「divの直下にあるaのテキストを得たい。直下で無い孫以下のaは得たくない」と言うことなら、CSSセレクターを使えるselectを使うのが楽です。

Python

1for link_01 in soup.select('div.bbb > a'): 2 print(link_01.text) 3for link_02 in soup.select('div.aaa > a'): 4 print(link_02.text)

aのテキストを取っているので、divの内側でaの外にある改行や空白は含まれませんが。

投稿2022/07/14 13:44

otn

総合スコア84505

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

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

idkohhi

2022/07/15 04:51

早速お返事ありがとうございます。select使うと楽でシンプルですね。find,find_Allを勉強し使ってました。これを機会にselect使ってみます。ありがとうございました。
guest

0

やり方は色々とあると思いますが、以下が考えられます(今回の場合ですと結果は同じになります)
test01, test02がaタグなのでそもそもaタグから取ってくる(やり方1)
test01はdivが2階層になっているので、それで判定する(やり方2)
test01のdiv class="aaa"で子要素のdiv class="bbb"で判定する(やり方3)

python

1from bs4 import BeautifulSoup 2 3html_doc = """ 4<html> 5<head> 6<meta charset="UTF-8"> 7<titlet></title> 8</head> 9<body> 10<div class="aaa"> 11 <div class="bbb"> 12 <a href="test01.html">test01です</a>? 13 </div> 14</div> 15<div class="aaa"> 16 <a href="test02.html">test02です</a> 17</div> 18</body> 19</html> 20""" 21 22soup = BeautifulSoup(html_doc, features="html.parser") 23 24# やり方1 25print("----やり方1----") 26for link in soup.find_all("a"): 27 print(link.text) 28 29# やり方2 30print("----やり方2----") 31for link in soup.find_all("div", class_="aaa"): 32 if link.div is not None: 33 print(link.div.a.text) 34 else: 35 print(link.a.text) 36 37# やり方3 38print("----やり方3----") 39for link in soup.find_all("div", class_="aaa"): 40 if link.div is not None: 41 class_list = link.div.get("class") 42 if (class_list is not None) and ("bbb" in class_list): 43 print(link.div.a.text) 44 else: 45 print(link.a.text) 46

投稿2022/07/14 13:37

編集2022/07/14 13:45
East_san

総合スコア407

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

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

idkohhi

2022/07/15 04:57

早速お返事ありがとうございます。#やり方3、が僕がやろうと考えてたやり方でした。classのAND+ORで判断するのですね。 現実に使うとif文が深くなるので、select勉強してみようかと思っています。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問