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

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

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

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

Q&A

解決済

3回答

1289閲覧

beautiful soup すぐ下の同レベルのタグの取得について

MitMc

総合スコア34

Python 3.x

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

0グッド

1クリップ

投稿2018/07/02 22:29

編集2018/07/02 22:47

下記のような構造のhtmlから、各<th>タグの直下の<td>タグを取得したい場合、取得が上手くいかないので教えていただけますでしょうか。下記の方法では出来たのですが、直感的ではないので、thタグのクラスを使って取得したいと考えてます。例えば、単勝のthのすぐ下のtdの2という数字や複勝のthの2番目の下のtdの170という数字を取得したいと考えてます。

取得したいHTMLの構造

<tr> <th class="tan">単勝</th> <td>2</td> <td class="txt_r">450</td> <td class="txt_r">2</td> </tr> <tr> <th align="center" class="fuku">複勝</th> <td>2<br/>5<br/>6</td> <td class="txt_r">170<br/>1,340<br/>310</td> <td class="txt_r">2<br/>12<br/>6</td> </tr> <tr> <th align="center" class="waku">枠連</th> <td>1 - 3</td> <td class="txt_r">1,170</td> <td class="txt_r">5</td> </tr> <tr> <th align="center" class="uren">馬連</th> <td>2 - 5</td> <td class="txt_r">21,850</td> <td class="txt_r">39</td> </tr> </table>

試したこと

上手く行ったやり方

リストの取得

①td_list=html.find_all("td")
②fuku = td_list[0]

上手くいかなかったやり方

上記のような取得の仕方ではなく、
①this_td = html.find("th", class_="fuku")
②fuku = this_td.sibling

のようなやり方でスクレイピングをしたいと思うのですが、エラーになります。

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

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

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

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

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

guest

回答3

0

ベストアンサー

確認しましたが、私の環境では html.find("th", class_='fuku') でも html.find("th", attrs={'class':'fuku'}) も問題なく動作しております。
(下記のサンプル)

ただ、this_td.next_siblings は改行コード\nも一つの要素として取得しているようで、this_td.next_sibling では得られる結果が"\n"となるようです。

個人的には select("th.fuku + td") を使ったほうが簡単に記述できる気がします。

Python

1from bs4 import BeautifulSoup 2import urllib.request 3 4html_data = """ 5<tr> 6<th class="tan">単勝</th> 7<td> 82</td> 9<td class="txt_r">450</td> 10<td class="txt_r">2</td> 11</tr> 12<tr> 13<th align="center" class="fuku">複勝</th> 14<td>2<br/>5<br/>6</td> 15<td class="txt_r">170<br/>1,340<br/>310</td> 16<td class="txt_r">2<br/>12<br/>6</td> 17</tr> 18<tr> 19<th align="center" class="waku">枠連</th> 20<td>1 - 3</td> 21<td class="txt_r">1,170</td> 22<td class="txt_r">5</td> 23</tr> 24<tr> 25<th align="center" class="uren">馬連</th> 26<td>2 - 5</td> 27<td class="txt_r">21,850</td> 28<td class="txt_r">39</td> 29</tr> 30</table> 31""" 32 33html = BeautifulSoup(html_data, "lxml") 34 35this_td = html.find("th", class_='fuku') 36print(list(this_td.next_siblings)) 37# ['\n', <td>2<br/>5<br/>6</td>, '\n', <td class="txt_r">170<br/>1,340<br/>310</td>, '\n', <td class="txt_r">2<br/>12<br/>6</td>, '\n'] 38 39this_td = html.find("th", attrs={'class':'fuku'}) 40print(list(this_td.next_siblings)) 41# ['\n', <td>2<br/>5<br/>6</td>, '\n', <td class="txt_r">170<br/>1,340<br/>310</td>, '\n', <td class="txt_r">2<br/>12<br/>6</td>, '\n'] 42 43td = html.select("th.fuku + td") 44print(td) 45# [<td>2<br/>5<br/>6</td>]

投稿2018/07/02 23:57

magichan

総合スコア15898

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

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

MitMc

2018/07/03 10:22

ご回答ありがとうございます。 td = html.select("th.fuku + td")を使用した場合、直下の1番目のtdは取得できるのですが、2番目を取得したい場合にどうしたら良いでしょうか。 td = html.select("th.fuku + td.txt_r")で取得できると思ったのですが空リストになってしまいました。
magichan

2018/07/03 11:42

select (cssセレクタ)の場合 '+' は隣接している要素となりますので html.select("th.fuku + td + td") となるかと思います。
MitMc

2018/07/03 12:11

出来ました。ありがとうございます!
guest

0

私なら(この構造が前提として)

this_td = html.find("th", class_="fuku") td_list = this_td.parent.find_all("td")

でtdのリストを得てから取り出しますね。

>>> from bs4 import BeautifulSoup >>> html = BeautifulSoup("""<tr> ... <th class="tan">単勝</th> ... <td>2</td> ... <td class="txt_r">450</td> ... <td class="txt_r">2</td> ... </tr> ... <tr> ... <th align="center" class="fuku">複勝</th> ... <td>2<br/>5<br/>6</td> ... <td class="txt_r">170<br/>1,340<br/>310</td> ... <td class="txt_r">2<br/>12<br/>6</td> ... </tr> ... <tr> ... <th align="center" class="waku">枠連</th> ... <td>1 - 3</td> ... <td class="txt_r">1,170</td> ... <td class="txt_r">5</td> ... </tr> ... <tr> ... <th align="center" class="uren">馬連</th> ... <td>2 - 5</td> ... <td class="txt_r">21,850</td> ... <td class="txt_r">39</td> ... </tr> ... </table> """, "lxml") >>> this_td = html.find("th", class_="fuku") >>> td_list = this_td.parent.find_all("td") >>> td_list [<td>2<br/>5<br/>6</td>, <td class="txt_r">170<br/>1,340<br/>310</td>, <td class="txt_r">2<br/>12<br/>6</td>]

投稿2018/07/03 00:43

編集2018/07/03 00:47
quickquip

総合スコア11038

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

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

0

テーブルの1行ずつのデータ取りたいってことですかね?
find_all(“tr”)してforとかで回せば取れそうですが試してみたでしょうか?

投稿2018/07/02 23:47

trewa-nek9585

総合スコア116

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問