はじめに
PythonでBeautifulSoupを使ってスクレイピングしていると、タグが取得できずに躓くことが多々あります。
解決してみると、なんだそんなことだったのか・・となるような初歩的な問題も多いのですが、
この記事の対象者はPython初心者、スクレイピングの初心者の方を想定しています。
前提知識
pythonを利用したwebスクレイピングに少しでも関わったことがある程度
環境
・Windows11
・Visual Studio Code
・Python3.7
1解析したHTMLの中身を見てみる
初期につまずいたのが、デベロッパーツールで表示されているHTMLと、BeautifulSoupで解析したHTMLの中身が違っている事象です。
タグを取得するときに、ChromeのデベロッパーツールなどでHTMLを見ながら作業していたのですが、解析自体は上手くいっているはずなのに特定のタグが取れないことがよくありました。
2時間以上もかけてあれこれ試行錯誤しても取れず、何かおかしいと思って解析結果を見てみると、デベロッパーツールでの表示と入れ子構造が違っていたのです。
かなり初歩的なミスですが、取得したHTMLがページのソースと必ずしも一致するとは限らないため、注意が必要ですね。
最初のうちは勉強もかねて毎回確認するくらいでもちょうどいいのかもしれません。
2動的なサイトを疑ってみる
これも初心者の頃に躓いたことです。
そもそもリクエストの時に取得できなかったり、とも関連するのですが取得したHTMLが実際のサイトのものと違っていてデータが取れなかったり・・・
それでブラウザのJavaScriptを切ってみるとほしい部分が表示されていないわけです。
この状態でrequestsを使っても取得できません。
SeleniumやPuppeteerなんかを使う必要があったのですが、取得できていない原因と理由が結びつくまでに時間がかかりました。
私の場合ほぼ独学でやっていたので、このあたりは教えてくれる人がいない状況での落とし穴ですね。
3関数を変えてみる
テキストやリンク、画像のurlなどを取得する際には、findかselectを使うことになると思います。
習得すればどちらでも取れるとは思いますが、findとselectともに中途半端な知識で、特性を考えずに使っていた時は、コードがごちゃごちゃになって頭を抱えていました。
一旦は以下のような理解で特性ごとに使い分けたら解決できたこともありましたので、どちらかで取れないときは関数を変えてみるのも手かもしれません。
select
入れ子構造から複数あるタグを探す
同じく入れ子構造がわかりやすい場合に、<li> とか <ul> なんかをとることが多いです
select_one
入れ子構造から特定のタグを探す
selectと同じく、入れ子構造が単純だと扱いやすいです
find_all
階層構造に依存せず、タグ名や属性で複数あるタグを探す
階層構造が複雑で、selectを使いこなせないうちは、こちらのほうが使いやすいかもしれません
find
階層構造に依存せず、タグ名や属性で特定タグを探す
入れ子構造が複雑で特定のデータだけ取りたい場合に
このあたりの知識は、おそらくこのページを読むような方は理解されているかもしれませんが・・・
おわりに
スクレイピングは難しくないとか、独学から副業で使えるようになるなんて文言はよく目にしますが、実際に手を動かしてみるとエラーだらけで、なぜうまくいかないのかわからず(特に納期前なんかは)絶望することがよくあります。
初歩的なミスだったりするわけですが、これで時間を持っていかれることもあるので厄介ですね。
同様のケースがたまったら、また記事にしたいと思います。