この記事では、Python+BeautifulSoupでWebスクレイピングする方法を紹介します。
スポンサーリンク
インストール
前準備として「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つの関数の違いが気になったので、まとめます。
関数の説明と、その使い分け方についても、解説したいと思います。
0 件のコメント:
コメントを投稿