2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

BeautifulSoup初心者のselectデバッグ手順

Posted at

はじめに

最近BeautifulSoupを使ったWebスクレイピングを学習中です。
特定の要素をCSSセレクタでselectしようとしても、空配列が返ってくることが結構多いので、
その場合の自分なりの対処法を、半分備忘録代わりに書こうと思います。
(今更感満載かもしれません)

もっと良いやり方知ってるよ!って方は優しく教えてください笑

書かないこと

  • Pythonのインストール手順
  • BeautifulSoup等ライブラリのインストール手順

環境

  • OS: Windows11
  • ブラウザ:Chrome
  • BeautifulSoupのバージョン: 4.11.1
  • Pythonのバージョン: 3.10.1

題材

カロリーSlimというサイトから、栄養素一覧を取ってくるというスクリプトを書いていたので、
こちらを題材にしたいと思います。
今回はあさりのみそ汁の栄養素を取ってきたいと思います。

selectを用いた要素取得

栄養素一覧を取ってくるとなると話が長くなるので、今回は食物繊維のグラム数を取得したいと思います
image.png
(題材をヨウ素取得にしましょうっていう洒落を利かせようと思いましたが、ややこしくなりそうなのでやめます)

まずはページ全体のパース

import requests
from bs4 import BeautifulSoup

url = "https://calorie.slism.jp/200293/"
res = requests.get(url)
soup = BeautifulSoup(res.content, "lxml")

取得したい要素(今回は0.68g)にマウスカーソルを合わせ、右クリック⇒検証
image.png

Chromeの開発者ツールが開くので、<span class="etc content">0.68</span>の箇所で、右クリック⇒Copy selector
image.png

コピーしたCSSセレクタを貼り付けて、中身を見てみます

result = soup.select('#etc > div > table > tbody > tr:nth-child(1) > td.valMeasure')
print(result)

> []

はい、空の配列が返ってきました。

デバッグしてみる

大体途中までは取得できているはずなので、結果が返ってくるまで子要素を消していきます。

result = sourp.select('#etc > div > table')
print(result)

> [<table style="width:100%;"> <tr> <td class="name">食物繊維 総量</td><td class="valMeasure"><span class="etc_content">0.68</span><span class="etc_unit">g</span></td> <td class="guide" style="text-align: right;">5.7g</td> </tr> <tr><td colspan="3"><div class="graph"><img height="8px" id="dietary_fiber_total_amountGraph" src="//cdn.slism.jp/calorie/images/bar01.gif" width="11.93%"/></div></td></tr> <tr> <td class="name">食塩相当量</td><td class="valMeasure"><span class="etc_content">1.76</span><span class="etc_unit">g</span></td> <td class="guide" style="text-align: right;">2.5g</td> </tr> <tr><td colspan="3"><div class="graph"><img height="8px" id="sodium_chloride_equivalentGraph" src="//cdn.slism.jp/calorie/images/bar01.gif" width="70.4%"/></div></td></tr> </table>]

tableタグまで遡ってようやく取得できました。
結果を見てみると、tableタグの次はtbodyタグではなくてtrタグになってますね。
tbodyタグを取っ払ってみます。

result = soup.select('#etc > div > table > tr:nth-child(1) > td.valMeasure')
print(result)

> [<td class="valMeasure"><span class="etc_content">0.68</span><span class="etc_unit">g</span></td>]

無事取得できました。
あとは、0.68という値を取得しにいきます。
spanタグのvalueになってるので、spanタグまで潜った方がよさそうですね。

result = soup.select('#etc > div > table > tr:nth-child(1) > td.valMeasure > span.etc_content')
print(result[0].contents[0])

> 0.68

欲しい要素を取得することができました。

おわりに

BeautifulSoupの細かい仕様を理解していないので、なんでtbodyタグが取得できなかったのかは分かりませんが、
ChromeのCSSセレクタとBeautifulSoupのパース結果が異なるから起きる事象なのかと思われます。
BeautifulSoupのパース結果を実際に見てみるってのが大事ですね。

Seleniumでもスクレイピングしたりしてるんで、Seleniumバージョンのデバッグ手順も今後書きたいと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?