Memorandum

普段の生活の覚え書き。主に技術録

【Python】スクレイピング

前回インストールしたPythonを使ってWebスクレイピングをやってみようと思います。

スクレイピングとは

スクレイピング(scraping)とは主にウェブサイトから情報を収集し、その情報を厳選・加工しデータを生成することです。 似たような言葉でクローリング(crawling)というのがあります。これは同じ様にウェブサイトから情報を収集するのですが、収集した情報を加工せずそのままのデータを使うことを指すことが多いようです。 GoogleGoogle botというサービスもクローリングの代表的な例です。

機械学習を行うために、大量のデータが必要になるのでスクレイピングによって多くのデータを集めます。

今回は本格的なスクレイピングの準備として、このサイトの記事名を集めてみました。

環境構築

  • Python 3.7.0
  • BeautifulSoup
  • urllib

BeautifulSoupとはPythonのライブラリの一つでスクレイピングに特化した機能を持っています。全ての機能を把握しきれていませんが、HTMLやXMLといった文章の構文解析をメインに使っています。

urllibはURLを扱うためのモジュールを集めたパッケージで下記のモジュールがあります。

  • urllib.request
    • URLを開いて読むためのパッケージ
  • urllib.error
    • urllib.requestが発生させる例外を持っている
  • urlib.parse
    • URLをパース(構文解析)するためのモジュール
  • urllib.robotparser
    • robots.txtファイルをパースするためのモジュール

今回は簡易的な試しということでurllib.requestだけを使いました。

urllibは最初から導入されているパッケージですが、BeautifulSoupの方はインストールする必要があります。Pythonのライブラリをインストールするためにpipというのを使います。 pipとはPythonのパッケージ管理ツールでMacだとHomebrewのようなもので、CentOSだとyumみたいなものです。pipは標準でPythonと一緒にインストールされているためそのまま使うことができるかと思います。

下記のコマンドでインストールします。

pip3 install beautifulsoup4

アルゴリズム

取得する前にサイトのソースを表示して記事名がどこに書かれているかを探します。 探すときはGoogle Chromeの開発者ツール(F12)を使うと便利です。

上図の赤枠ポインタのマークをクリックして、ソースを見たい部分をクリックするとその部分のソースが表示されます。

私のサイトでは"main"の中の"div id=list"の中に一覧として表示されているようです。 その中から"title"プロパティに記事名がありました。

そのため、このサイトの記事名一覧を取得するアルゴリズムとして下記の方法で実装しました。

  1. ページ下部の「次のページ」ボタンが表示されなくなるまで以下の2~5を繰り返す
  2. main_bodyにid:mainの要素を格納
  3. 2の要素の中から"div id=list"の要素を取得し格納
  4. 3の要素からtitleプロパティを抜き出し表示する
  5. 「次のページ」ボタンが示すURLを取得し、次の解析するURLに設定する

実装

以上から下記のような実装になりました。

クリックで開きます

# coding: UTF-8
import urllib.request
from bs4 import BeautifulSoup

# アクセスするURL
BASE_URL = "https://memoran.net"

# URLにアクセスする htmlが帰ってくる ⇨ <html><head><title>...
html = urllib.request.urlopen(BASE_URL)

# htmlをBeautifulSoupで扱う
soup = BeautifulSoup(html, "html.parser")

count = 0

# 次のページが存在する限り繰り返す
while True:
# 記事名を取得して表示
 main_body = soup.find("main", {"id":"main"})
 theme = main_body.find("div", {"id":"list"})
 for a in theme:
   print(a.get('title'))
   count += 1

 PAGER_NEXT = soup.find("a", {"class":"next page-numbers"})
 if PAGER_NEXT != None:
   NEXT_LINK = PAGER_NEXT.get("href")
   print()
   print(NEXT_LINK)
   html = urllib.request.urlopen(NEXT_LINK)
   soup = BeautifulSoup(html, "html.parser")

 if PAGER_NEXT == None:
   print()
   break

実行結果は以下のようになります。URLをそのまま表示するとカード形式で表示されてしまうので``付きに加工しています。

クリックで開きます

Pythonインストール方法
Vimの使い方
【Splatoon2】stat.inkを利用した戦績データの分析
【悲報】Xperia 画面割れ
【N予備校】実践サーバーサイドプログラミング完了
apacheからnginxへの移行検討
【WordPress】Cocoonでのページネーション変更
WordPressコンテナへのVim導入
WordPressのバックアップ
AMP対応のメリット・デメリット(問題点)

`https://memoran.net/page/2/`
dockerでローカルにwordpress環境を作る
ブラックジャックプログラムの実装
ブラックジャックの設計手法例
【M570】マウスチャタリング解消
【書評】UMLモデリングの本質
BlackJackプログラム
【WordPress】Cocoon導入
WPA/WPA2脆弱性
logwatchの活用例(不正アクセスの発見、対策)
PHPバージョンアップ

`https://memoran.net/page/3/`
EC-CUBEインストール(2)
EC-CUBEインストール(1)
SSL証明書更新
【N予備校】サーバーサイドプログラミング入門
コンテッサ購入(中古)
【Nintendo Switch】プロコン修理
【Splatoon 2】イカリング2をPCで閲覧
Docker導入
Markdown記法
MacBook Pro 修理

`https://memoran.net/page/4/`
ログインページへの対策
仮想化技術
【Nintendo Switch】ヒューマン・リソース・マシーン
埋め込み機能(embed)
Nmap
ペネトレーションテスト
攻撃手法
脆弱性の種類(2)
入学しました
セキュリティ用語集(セキュリティ対策とセキュリティ情報)

`https://memoran.net/page/5/`
セキュリティ用語集(脆弱性と攻撃手法)
脆弱性の種類(1)
fail2ban導入
迷路プログラム
豆苗生活
VPNのスヽメ
セキュリティについて
VPSのすゝめ
ブログデビュー

記事の総数は49

感想

Pythonを初めたばっかりですが、意外ととっつきやすくうまく思ったとおりに動いてくれました。 実行スピードもそれほど気にならなかったのですが、データ量が多くなると厳しいかも知れません。 サイトによってはAPIが用意されているところもあるので、APIを利用したスクレイピングにも挑戦していきたいです。