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

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

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

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

Beautiful Soup

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

Python 3.x

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

Q&A

解決済

1回答

2390閲覧

タグの中のいらないものを除去

mi2

総合スコア63

スクレイピング

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

Beautiful Soup

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

Python 3.x

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

0グッド

0クリップ

投稿2019/04/05 05:46

やりたいこと

pタグの中で、class等がない純粋な<p><p>で挟まれたもののみ抽出したい。

下記のコードにおいて、<p><p>で挟まれたAAA、BBB、CCCを抽出したいですが、pタグ内のspanやclassといったものが現状抽出されてしまいます。
どのようにすればよいでしょうか。

コード

~以上省略

soup = BeautifulSoup(html, 'html.parser') soup.select('p')

上記結果

<p><span>ZZZ</span></p>, <p>AAA</p>, <p>BBB</p>, <p>CCC</p>, <p class="tags">YYY</p>, <p class="list"><a href="/WWW/"><img alt="VVV" src="/UUU"/></a></p>, <p class="tags">TTT<br class="sp"/>SSS</p>, <p class="hoge"><a class="tagb" href="/socialmedia/">RRR</a></p>, <p class="fuga"><a class="typesquare_tags" href="/chronicle/04/">4</a></p>, <p class="capion typesquare_tags">XXX</p>

soup.select('p')の方法を変えるのが良いか、アウトプットから正規表現で消す等を試行錯誤しています。
宜しくお願いいたします。

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

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

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

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

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

mi2

2019/04/05 05:59

soup.select('p').textは出来ませんが、for文の中で.textメソッドは利用可能です。
mi2

2019/04/05 06:30

はい。できます。
guest

回答1

0

ベストアンサー

attrs に検索するタグの属性の条件を指定でき、ここには関数を指定することができます。
関数を指定した場合、引数として属性名がキー、属性値が値の dict オブジェクトが渡されます。
属性が1つもないということは空のdict {} が渡ってくるということなので、dict が空の場合は True、そうでない場合は False という関数を指定しておけばよいです。

python

1html = '''<p><span>ZZZ</span></p>, 2 <p>AAA</p>, 3 <p>BBB</p>, 4 <p>CCC</p>, 5 <p class="tags">YYY</p>, 6 <p class="list"><a href="/WWW/"><img alt="VVV" src="/UUU"/></a></p>, 7 <p class="tags">TTT<br class="sp"/>SSS</p>, 8 <p class="hoge"><a class="tagb" href="/socialmedia/">RRR</a></p>, 9 <p class="fuga"><a class="typesquare_tags" href="/chronicle/04/">4</a></p>, 10 <p class="capion typesquare_tags">XXX</p>''' 11 12from bs4 import BeautifulSoup 13 14soup = BeautifulSoup(html) 15vals = [t.text for t in soup.find_all('p', attrs=lambda attrs: not attrs)] 16print(vals) # ['ZZZ', 'AAA', 'BBB', 'CCC']

追記

単純に p タグの値だけ取り出すという意味でしたら、以下です。

python

1html = '''<p><span>ZZZ</span></p>, 2 <p>AAA</p>, 3 <p>BBB</p>, 4 <p>CCC</p>, 5 <p class="tags">YYY</p>, 6 <p class="list"><a href="/WWW/"><img alt="VVV" src="/UUU"/></a></p>, 7 <p class="tags">TTT<br class="sp"/>SSS</p>, 8 <p class="hoge"><a class="tagb" href="/socialmedia/">RRR</a></p>, 9 <p class="fuga"><a class="typesquare_tags" href="/chronicle/04/">4</a></p>, 10 <p class="capion typesquare_tags">XXX</p>''' 11 12from bs4 import BeautifulSoup 13 14soup = BeautifulSoup(html) 15vals = [t.text for t in soup.find_all('p')] 16print(vals) # ['ZZZ', 'AAA', 'BBB', 'CCC', 'YYY', '', 'TTTSSS', 'RRR', '4', 'XXX']

追記

python

1html = '''<p><span>ZZZ</span></p>, 2 <p>AAA</p>, 3 <p>BBB</p>, 4 <p>CCC</p>, 5 <p class="tags">YYY</p>, 6 <p class="list"><a href="/WWW/"><img alt="VVV" src="/UUU"/></a></p>, 7 <p class="tags">TTT<br class="sp"/>SSS</p>, 8 <p class="hoge"><a class="tagb" href="/socialmedia/">RRR</a></p>, 9 <p class="fuga"><a class="typesquare_tags" href="/chronicle/04/">4</a></p>, 10 <p class="capion typesquare_tags">XXX</p>''' 11 12from bs4 import BeautifulSoup 13 14soup = BeautifulSoup(html) 15 16vals = [] 17for t in soup.find_all('p'): 18 # p タグの子でテキストがある要素のみ検索 19 p_text = t.find(text=True, recursive=False) 20 if p_text: 21 vals.append(p_text) 22print(vals) # ['AAA', 'BBB', 'CCC', 'YYY', 'TTT', 'XXX']

投稿2019/04/05 06:18

編集2019/04/05 06:53
tiitoi

総合スコア21954

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

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

mi2

2019/04/05 06:30 編集

ありがとうございます。 <p><span>ZZZ</span></p>のZZZは取得したくないのですが、attrsもしくはlambda関数で制御できますでしょうか。 <p>タグの<span>に入ってくるものについては外したいです。
tiitoi

2019/04/05 06:54

追記しました。 各pタグに対して、以下を実行すると、p タグの子でテキストがある要素のみ取得できます。 t.find(text=True, recursive=False) もしなければ None が返るので、そうでない場合だけリストに追加していけばよいでしょう。
mi2

2019/04/05 07:08

ありがとうございます。 確かに、p タグの子でテキストがある要素のみ取得できます。 ただ、今度は以下p classの方が取得されるようになってしまいました。 <p class="tags">YYY</p>, <p class="list"><a href="/WWW/"><img alt="VVV" src="/UUU"/></a></p>, <p class="tags">TTT<br class="sp"/>SSS</p>, <p class="hoge"><a class="tagb" href="/socialmedia/">RRR</a></p>, <p class="fuga"><a class="typesquare_tags" href="/chronicle/04/">4</a></p>, <p class="capion typesquare_tags">XXX</p>'''
tiitoi

2019/04/05 07:15

最初の p タグを検索するところを soup.find_all('p') を soup.find_all('p', class_=False) にすれば、class 属性があるのは対象外にできます。
mi2

2019/04/05 07:17

失念しておりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問