スキップしてメイン コンテンツに移動

Python + BeautifulSoup4でWebサイトをスクレイピング

この記事では、Python+BeautifulSoupでWebスクレイピングする方法を紹介します。

HTMLコードのイメージ

インストール

前準備として「Requests」と「BeautifulSoup」をpipでインストールします。

pip install requests
pip install beautifulsoup4

注意事項

Pythonに限らず、Webスクレイピングでは、ルールを守ってスクレイピングしないと、法的に訴えられる事もあるので、ルールを守って開発しましょう。

# スクレイピング、クローリングする時の注意点
岡崎市立中央図書館事件(Librahack事件) - Wikipedia

サンプルコード

以下のサンプルHTMLから、今日の日経平均を取得するのPythonのコードです。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ページタイトル</title>
</head>
<body>
  <div class="today">
    <h1>今日の日経平均は</h1>
    <p>10,000円</p>
  </div>
  <div class="yesterday">
    <h1>昨日の日経平均は</h1>
    <p>9,000円</p>
  </div>
</body>

[Python]

import requests
from bs4 import BeautifulSoup

#スクレイピング対象のURL (今回はローカルサーバのHTMLファイルを対象にする)
target_url = "http://127.0.0.1/sample.html"

#requestsを使って、GETリクエストを送信
r = requests.get(target_url)
#レスポンスのHTMLを解析
soup = BeautifulSoup(r.text, 'html.parser') 

#今日の日経平均が格納されているタグを抽出する (div.today > p)
div = soup.find('div', class_="today")
p = div.find("p")
print(p.string)  #=> 10,000円

BeautifulSoupのいろいろな使い方

Python+BeautifulSoupで、Webスクレイピングするときによく使う関数を紹介します。

一致するタグをすべて抽出

for a in soup.find_all("a"):
  print(a.get("href"))

見つかった最初のタグを抽出

soup.find("a")

抽出したタグから値を取得する

  • 属性値の取得
soup.find("a").get("href")
  • タグの中の文字列を取得
soup.find("a").string

タグを抽出する条件を指定する

soup.find("a", class_="classname", href="/page1.html")

※classなどのPythonの予約語を条件を指定する場合は、後ろにアンダーバーが必要です。

以下の書き方でもOK

soup.find_all("a", attrs={"class": "classname", "href": "page1.html"})

正規表現を使ったタグの抽出

  • hから始まるタグを抽出(h1〜h6)
import re
soup.find_all(re.compile("^h"))
  • 拡張子.jpgにリンクしているタグを抽出
soup.find_all(href=re.compile("\\.jpg$"))
  • タグの中の文字列を正規表現で検索
soup.find_all(text=re.compile("Python"))

タグ(要素)名の取得

soup.find(class_="classname").name

CSSセレクタを使ってタグを抽出

CSSセレクタを使ってタグを検索することもできます。CSSセレクタを使うと、かなり柔軟な検索処理が行え、さらにPythonのコードもスッキリします。

classセレクタ

soup.select(".myclass")

# クラス名をAND条件で検索
soup.select(".car.prius")

IDセレクタ

soup.select("#myid")

要素セレクタ

soup.select("a")

属性セレクタ

# href属性を持つ aタグを抽出
soup.select('a[href]')

# 完全一致
soup.select('a[href="page1.html"]')

# 先頭が一致
soup.select('a[href^="http://example.com/"]')

# 末尾が一致
soup.select('a[href$=".jpg"]')

# 部分一致
soup.select('a[href*="hello"]')

タグの親子関係を指定するセレクタ

# 子孫セレクタ (p配下のaタグがすべて抽出される)
soup.select("p a")

# 親子セレクタ (p直下のaタグが抽出される)
soup.select("p > a")

# 隣接セレクタ (pタグ直後に隣接しているaタグが抽出される)
soup.select("p + a")

複数のセレクタをOR条件で指定

複数のセレクタを指定するには、カンマ区切りで記述する。
この時、いずれかのセレクタに一致した場合にタグが抽出される。(OR条件)

# jpg,pngにリンクしているaタグを抽出
soup.select('a[href$=".jpg"], a[href$=".png"]')

CSSセレクタで見つかった先頭1見目のタグを抽出(select_one)

CSSセレクタで見つかった最初の1件を返す方法です。select_oneはCSSセレクタで指定した条件にヒットするタグが、1つだけと分かっている場合や、複数一致した中の先頭1件を取得した場合などに使用します。

soup.select_one("#myid")

指定要素の子孫タグを含めたすべてのテキスト取得する方法

BeautifulSoupの.stringは、以下のようなネストしたタグ構造の場合、うまくテキストを取得できません。

<div class="parent">
  <p>テキスト</p>
  <div>
    <span>テキスト</span>
  </div>
</div>

上記のようなネストしたタグから、一括してテキストを取得する場合は、以下のように書きます。

  children = soup.find("div", class_="parent").find_all()
  text_list = []
  for child in children:
    text_list.append(child.string or "")
  return "".join(text_list)

まとめ

Python+BeautifulSoupで、Webスクレイピングを行う方法を紹介してきました。正規表現や、CSSセレクタをマスターすれば、自由に欲しい情報が手に入ると思います。ルールを守ってスクレイピングを楽しみましょう。

この記事以外にも、PythonでWebスクレイピングを行う方法を紹介しているサイトは沢山あります。Webスクレイピングを始めるならPythonがおすすめです!

関連記事

MacにPython3をインストールする! (サクッとインストールしたい人向け)

Mac環境に、Python3を簡単にインストールする方法を紹介しています。

Python3入門! 基礎をおさらい (変数/演算子/条件分岐/繰り返し)

1つの記事に、基本文法をまとめて書いているので、時間が空いて忘れてしまった場合でも、一気に復習出来るようになっています。よければ見てください。

Flaskでソースの変更を検知して、Webアプリを自動リロードする[Python Tips]

Flaskの開発で、ソースを更新したら、自動的にWebアプリをリロードする方法です。

Flaskで REST API開発する! 直ぐに実行できるサンプルコードで解説 【Python Tips】

Pythonの軽量Webフレームワークである、FlaskでREST APIを作るまでの流れを、紹介します。

Flask-RESTful を使って、REST APIを作る【Python Tips】

Flaskと、Flask-RESTfulを使って、REST APIを作ります。
Flask-RESTfulを使うと、オブジェクト思考な感じで、REST APIが作れます。

Pythonで小数点の四捨五入/切り捨て/切り上げを行う

Pythonのdecimalモジュールを使って、小数点の丸めを行う方法です。

pipコマンドまとめ! 忘れても思い出せばいい! 【Python TIPS】

よく使うpipコマンドをまとめました。

Pythonで正規表現を使って数値/英字チェックを実装する (コピペ用)

数値/半角英字などのチェック処理を、Pythonの正規表現を使って実装します。
コピペで簡単に使えるようになっています。

[SQLAlchemy] one() / first()の違いと使い分け

PythonのSQLAlchemyで、1件のレコードを取得する関数に、one()とfirst()関数の2つがある。
この2つの関数の違いが気になったので、まとめます。
関数の説明と、その使い分け方についても、解説したいと思います。

スポンサーリンク
スポンサーリンク
スポンサーリンク

コメント

このブログの人気の投稿

axiosの使い方まとめ (GET/POST/例外処理)

axiosの使い方まとめ (GET/POST/例外処理)最近何かとよく使うJavaScriptでAJAX通信を行うaxiosについて、簡単に使い方をまとめました。GETリクエストをaxiosで送るまずはGETリクエストをaxiosで送る方法です。const res =await axios.get('/users') console.log(res.data)分割代入の記法を使うと、以下のようにも書けますconst{data}=await axios.get('/users') console.log(data)クエリパラメータ (URLパラメータ)を指定クエリパラメータを指定する方法は2つあります。1つ目は、axios.getに指定するURLに直接記述する方法です。axios.get('/user?id=123')2つめは、axios.getの第2引数に、オプション指定する方法です。axios.get('/user',{ params:{ id:123}})POSTリクエストをaxiosで送る次はPOSTリクエストをaxiosで送る方法です。JSON形式でPOSTするJSON形式でPOSTする場合は、axios.postの第2引数に、送信するデータをJavaScriptオブジェクトで指定します。const res =await axios.post('/user',{ id:123, name:'Yamada Tarou'})application/x-www-form-urlencoded形式でPOSTするapplication/x-www-form-urlencoded形式でPOSTする場合は、URLSearchParamsを使います。var params =newURLSearchParams() params.append('id',123) params.append('name','Yamada Tarou')const res =await axios.post('/user', params)axios でファイルをアップロードする画像などのファイルを、axiosでアッ…

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決する

[VB, C#] Windows 8, Window 10 で ImeModeが制御できない問題を解決するタイトルの通りですが、Windows 8 以降では Windows Form アプリケーションで、コントロールの ImeMode に Katakana や KatakanaHalf を設定しても、カタカナになってくれません。なぜ ImeMode が効かないのか?Windows 8 以降、IME Mode の切り替えは、ユーザー単位で切り替わるようになった為、アプリから IME Mode 制御が出来ないようになりました。
(IME をON にした場合、常に ひらがな モードになます)※ Windows 7までは、IME Modeの切り替えはアプリ単位で行われていた為、問題なくアプリから IME制御が行えました。対処方法Windows 8 以降、IMEの制御は、InputScope クラスの利用が推奨されています。
しかし、InputScope クラスは、WPF、Windows ストアアプリでしか使えない為、Windows Formアプリでは使用できません。
(Windows Form はもう使うな!という事でしょうか (涙) )結論としては、コントールパネルの設定で、IMEの制御をユーザ単位から アプリ単位に変更する事ができます。
これで、Windows Formアプリでも 従来通りIMEの制御を行う事が出来ます。おわりにこの方法だと、アプリをインストールする端末すべてに設定が必要となり、とっても面倒です。。。
しかし、今の所これしか方法がない状態です。
これからは Windows Formではなく、WPFや Windows ストアアプリで作れという事ですかね (^^;)

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]

MailKitの使い方! エンコーディング指定や添付ファイをメールで送信する方法[C#/VB Tips]MailKitを使ってメールを送るサンプルコードです。(C#)UTF8/iso-2022-jpのエンコーディング指定、GMail/YahooのSMTPサーバで送るなど、4つのサンプルコードでMailKitの使い方を紹介します。MailKitって何?2017年に.NET標準のSystem.Net.Mail.SmtpClientが廃止予定となり、Microsoftより今後はオープンソースライブラリである、MailKitに置き換えるとアナウンスがありました。既にSmtpClientは非推奨になっており、今後は廃止されていきます。現在、SmtpClientを使用したソースコードには、Visual StudioからMailKitを使うよう警告が出るようになっています。さっそく、MailKitを使ってメールを送信するサンプルコードを作っていきます。UTF8でメールを送信文字エンコーディングを、UTF8でメールを送信するサンプルコードです。
MailKitは、デフォルトの文字エンコーディングがUTF8なっている為、シンプルなコードでメールを送信する事ができます。var host ="<smtp server name>"; var port =25;// or 587using(var smtp =new MailKit.Net.Smtp.SmtpClient()){//SMTPサーバに接続する smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto);//認証が必要な場合は、以下のコメントを解除//smtp.Authenticate("<id>", "<password>");//送信するメールを作成する var mail =new MimeKit.MimeMessage(); var builder =new MimeKit.BodyBuilder(); mail.From.Add(new MimeKit.MailboxAddress("",&quo…