Loading
BLOG 開発者ブログ

2022年12月26日

PythonでWebデータを収集する方法(スクレイピング)



この記事は アイソルート Advent Calendar 2022 23日目の記事です。
前日はtakahashinさんの
半年Tableauを使ったら分析LvがMAXになってました」でした。

こんにちは。クラウドソリューショングループのhasekです。
データ分析が最近注目され始め、需要が高まっており、将来性が高いので勉強し始めました。
データ分析に興味をもっている人のために、記事として書こうと思います。

【目次】

本記事の狙い

この記事は読者がデータの種類とビッグデータの収集方法を知り、興味を持ってもらった上でデータ収集することができるようになるのが狙いです。

Pythonを用いる理由

統計分析をする上で、ExcelやR言語、SPSSなどがあげられますが、
ここで私がPythonを用いてデータ収集、分析を行う理由として以下の理由があります。

① 複雑な計算が容易にできる

Excelは表を用いて簡単にデータを分析することができ、マクロを用いるとある程度の複雑な処理も可能です。
しかし、定形的な処理でないと分析が難しい点や、インターネットの膨大なデータ、ビッグデータを解析するには、処理が重くなってしまいます。

② 統計分析と他の処理の連携が容易

R言語では、希望するライブラリがあればすぐに統計分析が可能で、かつプログラミングスキルがあれば、複雑な解析も可能です。
しかし、解析した結果をほかの処理に入れたり、他言語との連携をしたりすることは容易ではないです。
PythonはExcelに比べ、ハードルは高いですし、R言語より統計に特化していませんが、
それに対してPythonは他方でのプログラミング環境でも優れており、②の観点からとても優れた言語であるといえます。

データとは?データの種類

世の中で扱われるデータの種類は様々です。
大きく分類すると「定性的なデータ(質的データ)」、「定量的なデータ(量的データ)」にわけることができ、
さらに定性的なデータには、「名義尺度」、「順序尺度」にわけられ、定量的なデータには「感覚尺度」、「比例尺度」にわけることができます。
データの違いと例
定性的なデータ 定量的なデータ
名義尺度 順序尺度 間隔尺度 比例尺度
説明 区別する言葉 数の順序、大小 間隔に意味がある 物事の数値で表す
性質 計算不可 大小比較可 差や和の計算可
比率の意味無し
和、差、比率どれもできる
名前、血液型 スポーツの順位,アンケート(1.好き、2.やや好き・・) 1日=24時間など、定義が決まっているもの 身長、体重、各地の天気等々
※詳しくは書籍「Pythonによる統計分析入門」に記載

スクレイピングとは

スクレイピングとは

スクレイピング(Scraping)は「こする」「かき集める」といった意味を持つ「Scrape」に由来する用語で、
「Scrape」は広範囲をゴシゴシこすりながら物をきれいにしたり、散らばった物を集めたりするニュアンスが近いです。
そこからコンピュータ用語に転じて、特定の目的を持ってWebやデータベースを広く探って「データを抽出する手法」のことを指すようになりました。

スクレイピングとクローリングの違い

同じくWeb上で行われる情報収集手法に「クローリング(Crawling)」があります。
スクレイピングが「特定の情報を抽出する」のに対し、クローリングは「巡回してWebの構造や要素を探る」点で大きな違いがあります。

Pythonの事前準備

Pythonのインストール

Windows
1.下記URLからインストーラをダウンロード

https://www.python.org/ftp/python/3.11.1/python-3.11.1-amd64.exe

2.手順に従ってインストール

Mac
標準搭載なのでインストール不必要

Pythonの事前準備「requests」,「beautifulsoup4」ライブラリの取得

ターミナル上で

pip install requests
pip install beautifulsoup4

を入力し実行

※正常にダウンロードされない場合

パスが通っていない

以下のコマンドを入力

py -m pip install ***

ネットワークが接続できない

プロキシサーバーのURLとポート番号が必要です。

URL:proxy.example.com port:8080 のとき

set HTTPS_PROXY=http://proxy.example.com:8080
pip install ****

※認証が必要な場合
ユーザーとパスワードの入力が必要です。
ユーザー名:user パスワード:pass のとき

set HTTPS_PROXY=http://user:pass@proxy.example.com:8080
pip install ****

詳しくは下記URL

https://gammasoft.jp/support/pip-install-error/

スクレイピング手順

スクレイピングでは、最初に「どんな情報が欲しいか」を定義します。
今回実践としてQiitaのタグのランキングを取得してみましょう。
(使用するWebサイト:Qiitaタグ一覧:https://qiita.com/tags)

1.ページから取得したい情報を決める

取得したい情報を

  • タグ名
  • タグごとの記事数
  • 記事数でのランキング

3つ取得すると仮定します。

2.欲しいデータの要素を調べる

1.F12で開発者ツールを開きます。

2.下記をクリックします。

青く光っているとOKです。

3.知りたい要素のパラメータをクリックします

カーソルを合わせるとハイライト表示され、
クリックすると該当要素が左で青くハイライトされます。
これで知りたいパラメータの要素が
Python icon Python ・・・・

必要なデータが、クラスが「TagList__item」の中の

・テキストのデータ(Python)
・タグ内の「data-count」のパラメータ(68440)

であることがわかりました。
ここからPythonのコードに入っていきます。

Pythonコーディング手順

サンプルコード

import requests
from bs4 import BeautifulSoup

url = "https://qiita.com/tags?page="
pageLength = 10
rank = 0
for page in range(pageLength):
    req = requests.get(url+str(page))                    #・・・①
    soup = BeautifulSoup(req.content, "html.parser")     #・・・②
    tagsData = soup.findAll('div',class_='TagList__item')#・・・③
    for tagData in tagsData:
        rank +=1
        count = tagData.get('data-count')                #・・・④
        tagText = tagData.text                           #・・・⑤
        print(rank,'位:',tagText,'  ',count,'件')

①Webページにアクセスする

ページにリクエストを送って、
以下のWebのデータをレスポンスとしてもらっています。

Responseオブジェクト
├url: url属性
├ステータスコード: status_code属性
├エンコーディング: encoding属性
├レスポンスヘッダ: headers属性
├テキスト: text属性
└バイナリデータ: content属性

requestsの使い方の詳細は以下URL

②BS4で取得したWebデータを指定した形式で(今回はhtml)取得する

BeautifulSoup(解析対象のHTML/XML, 利用するパーサー)

を使うことによって、Webページの要素を取得することができます。

使用できるパーサー
パーサー 引数での指定方法 特徴
Python’s html.parser “html.parser” 追加ライブラリが不要
lxml’s HTML parser “lxml” 高速に処理可
lxml’s XML parser “xml” XMLに対応し、高速に処理可
html5lib “html5lib” 正しくHTML5を処理可

今回は「Python’s html.parser」を使用します

③指定したタグでページ内のデータを抽出する

Webデータからページを取り出した後
要素を指定して、欲しい要素のみに抽出していきます。
全体の要素という「スープ」から、必要なデータ「具材」を掬い取るイメージです。

取り出した要素.findAll(絞り込みたいタグ名[,追加条件])

ここではタグが「div」であり、クラスが「TagList__item」である要素を抽出しています。

今回はタグに一致する要素を全て抽出するため「findAll」を使っていますが、
他にも以下が使用できます。

タグ、条件に最初に合致した要素を取得

.find(タグ名[,追加条件])

タグ、条件に合致した要素をすべてリストで取得

.find_all(タグ名[,追加条件])

CSSセレクタに合致した要素をすべてリストで取得

.select(“CSSセレクタ”)

また、抽出した要素から再度抽出することが可能です。

originalSoup = BeautifulSoup(req.content, "html.parser")
soup1 = originalSoup.find("a")
soup2 = soup1.findAll("div")

④抽出したデータのタグの値を取得する

タグ内で指定されている数値等を抽出しています。

tagData.get(タグ名)

このようなタグ内のパラメータ、ハイパーリンクのURLを取得するために用いられることが多いです。

tagData.get("href")

⑤抽出したデータのタグ以外、textデータを取得する

抽出したhtml要素から、タグ情報を抜いて、表示されているテキストのみ取得しています。

テキストを抽出したい要素.text

実行結果

最後に

今回はデータの収集方法のひとつとして、スクレイピングを取り上げました。
今回使用したBeautifulSoupには、まだまだほかの抽出方法などがあり、自由に収集できますので、
興味を持っていただけたら是非挑戦してみてください!
beautifulSoup公式ドキュメント:http://kondou.com/BS4/

明日はmiyajimayさんの
Auth0ダッシュボードからメトリクスを見れるようになったらしい 」です!
お楽しみに!


link to CloudFlag

ananのブログ