webページ内のテキストデータを自動で抽出(Beautiful Soup)
前回までは
Python 無料で独習 Webスクレイピング入門 vol 01
Python 無料で独習 Webスクレイピング入門 vol 02
Seleniumをもちいてwebスクレイピングを実装しましたが、
今回はBeautiful Soupというメソッドを使用して
webスクレイピングを実装するそうです。
Beautiful Soupとは
HTMLの構造を解析する目的で用いられるライブラリ
今回の講義の目標
公開の講義につかうサイトは
今西航平先生が講義用に作成したサイトを利用します。
URLはこちらです。
https://scraping-for-beginner.herokuapp.com/udemy
お若いのにとても立派な経歴です。
余談ですが今西先生のTwitterをフォローしているのですが、
今西先生は現在株式会社キカガクを退社されて
新しい道へ進んでおられるようです。
本題に戻りますが、今回の講義の目標は
・受講生の数
・レビューの数
をBeautiful Soupを使って取得するそうです。
まずは必要なライブラリをインストールします。
Beautiful Soupと
requestsです。
!pip install requests
#B S は大文字です。
!pip install BeautifulSoup4
Beautiful SoupでHTMLの構造を解析
インストールが完了したら、次はimportです。
import が完了したら今回スプレイビングするアドレスを
変数urlにいれます。
そのurl情報をrequests.get()メソッドで取得し
インスタンスをres とします。
import requests
from bs4 import BeautifulSoup
res
url = 'https://scraping-for-beginner.herokuapp.com/udemy'
res = requests.get(url)
res
<Response [200]>
#この200は取得が成功したことを意味します。
res.text とすると実際のwebページのデータがズラ~っとでます。
ただ改行とかがされていないのでとても見にくいです。
type(res.text)
str
タイプを調べると単なる文字列データであるとわかります。
そこでBeautifulSoupを使うそうです。
BeautifulSoupの引数にres.textを渡します。
'html.parser' を入力することでHTMLの構造を解析できます。
soup = BeautifulSoup(res.text,'html.parser')
soup
find_allで情報を取得
ずいぶんと見やすくなりました。
さらに
print(soup.prettify())
とするとインデントがされてさらに見やすくなります。
それでは先ほど作成したHTMLが入ったインスタス
soupに対して操作をおこないます。
seleniumの時にも出てきあfind_allをつかいpタグの情報を全て取得します。
soup.find_all('p')
[<p>
こちらのページは、<b>PythonによるWebスクレイピング〜Webアプリケーション編〜</b>で使用します。
</p>,
<p><b><p class="position">株式会社キカガク 取締役副社長</p></b><br/>
東京理科大学在学中に株式会社キカガクに1人目の正社員としてジョイン。大学時代4年間、塾講師として「教育」に熱中し、300名以上の中高生の授業を担当。<br/>
</p>,
<p class="position">株式会社キカガク 取締役副社長</p>,
<p class="subscribers">受講生の数:10796</p>,
<p class="reviews">レビューの数:1831</p>]
そうするとリスト形式で情報を取得できます。
この情報の中で受講生の数の部分をみると
<p class="subscribers">受講生の数:10796</p>,
となっています。
なので情報を特定するために、このclassで指定します
subscribers = soup.find_all('p',attrs={'class':'subscribers'})[0]
subscribers
<p class="subscribers">受講生の数:10796</p>
subscribers.text
'受講生の数:10796'
これで一応'受講生の数:10796'まで取得できましたが
こでだと文字列strです。
必要なのは数なので、int型で抽出します。
'受講生の数:10796'
まずsplit(':')で:を境に前と後ろに文字列を分けます。
分けられた文字列はリスト型で格納されるので、
subscribers.text.split(':')[1]
として後ろの数字部分だけを抽出します。
この時点でも文字列のままなので
int()でint型に変換します。
int(subscribers.text.split(':')[1])
10796
これで受講生の数をint型で取得することができました。
余談なのですが、動画の中で受講生は9375となっているのですが、
2021/2/12現在では10796となっいます。
確実に受講生が増えていっているのですね~。素晴らしい!
レビューの数もclass を reviews に変えると実装することができます。
reviews = soup.find_all('p',attrs={'class':'reviews'})[0]
n_reviews = int(reviews.text.split(':')[1])
n_reviews
1831
CSSセレクタで情報を取得
最後にCSSのお話です。
CSSセレクタとは
CSSによるデザイン指定をどのHTML要素に適用させるかを指定する
.クラス名 で情報を特定することができます。
soup.select_one('.subscribers')
<p class="subscribers">受講生の数:10796</p>
soup.select_one('.reviews')
<p class="reviews">レビューの数:1831</p>
取得方法がいろいろあって今回はこちらの二つを学びました。
find_all():「要素名」に続いて「属性」を引数で指定
select() : 「CSSセレクタ」で指定
今西先生、本日も楽しい講義を有難うございました!
コメント