PythonでWebスクレイピングを行う方法を解説します。
ここでは入門編として、Webスクレイピングできること、使用ライブラリと使い方を具体的な事例を用いて紹介します。
Webスクレイピングでできること
Webスクレイピングとは、Webページから情報を取得することを指します。
Pythonを利用することによって取得したデータを加工・編集してExcelなどに保存することが可能となります。また情報の取得や加工などをスクリプトとして実行することで、作業を自動化することができます。
ここでは、PythonでWebスクレイピングを行うための方法を、以下の手順で解説していきます。
- Webスクレイピング用のライブラリの説明。
- WebページのHTMLを取得する。
- 取得したHTMLを解析して、特定の情報を抽出する。
使用ライブラリ
PythonでWebスクレイピングを行うためのライブラリでよく利用されているものは Requests
, Beautiful Soup
, Selenium
, Scrapy
があります。
ここでは、初心者にとって扱いやすい Requests
, Beautiful Soup
の使い方を解説していきます。
Requests
がHTMLのダウンロード、Beautiful Soup
がHTMLデータの解析・抽出の役割を担います。
インストール:必要
インストール:必要
Javascriptやログイン、セッション管理等があるページをスクレイピングするには、Selenium
が必要になります。
インストール
pip
コマンドでRequests
, Beautiful Soup
ライブラリをインストールします。
・関連記事:Pythonライブラリのインストール(pipの使い方)
Successfully installed ・・・・と表示されればインストールは成功です。(依存関係のある他のライブラリも同時にインストールされます。)
Requestsの基本的な使い方
Requests
はHTTP通信用のライブラリで、HTMLやXMLデータを取得する為に使われます。
記述方法は以下のようになります。
ここでは例として技術評論社の新刊書籍ページの情報を取得してみます。
1 2 3 4 5 6 | import requests response = requests.get('https://www.yahoo.co.jp/') print(response.status_code) # 200 |
Requests
のget()
メソッドの引数に対象ページのURL(https://gihyo.jp/book/list)を指定します。
指定のURLに接続すると、戻り値として response
オブジェクトが返ってきます。
例では、response
の属性値であるstatus_code
が200となっている為、正常に取得出来ている事が分かります。(ステータスコードの詳細はこちらを参照ください)
response
オブジェクトの主な属性は以下になります。
属性 | 説明 | 値 |
---|---|---|
status_code | ステータスコード | 200番台:成功 300番台:リダイレクト 400番台:クライアントエラー 500番台:サーバエラー |
headers | レスポンスヘッダの内容 | {‘Accept-Ranges’: ‘none’, ‘Cache-Control’: ‘private, no-cache, no-store, must-revalidate’, ‘Content-Encoding’: ‘gzip’, ‘Content-Type’: ‘text/html; charset=UTF-8’, ‘Date’: ‘Sat, 26 Feb 2022 05:52:35 GMT’, ・・・} |
text | レスポンスの内容 (HTML) | (‘<!DOCTYPE html><html lang=”ja”><head> <meta charSet=”utf-8″/> <meta ‘ ‘http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/><title>Yahoo! ‘ ‘JAPAN</title>・・・’) |
encoding | エンコーディング | UTF-8 |
取得したHTMLの内容を表示するには以下のように記述します。
1 | print(response.text) |
結果は以下のようになります。
<html lang=”ja”>
<head prefix=”og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#”>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<title>書籍一覧新刊|技術評論社</title>
<meta name=”description” content=”” />
<meta name=”keywords” content=”技術評論社,gihyo.jp,” />
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
<meta http-equiv=”Content-Script-Type” content=”text/javascript” />
<meta http-equiv=”Content-Style-Type” content=”text/css” />
<meta name=”twitter:card” content=”summary_large_image”/>
<meta name=”twitter:site” content=”@gihyo_hansoku”/>
<meta property=”og:title” content=”書籍一覧新刊” />
<meta property=”og:type” content=”article” />
<meta property=”og:description” content=”” />
<meta property=”og:url” content=”https://gihyo.jp/book/list” />
<meta property=”og:image” content=”https://image.gihyo.co.jp/assets/images/gh_logo.png” />
<meta property=”og:site_name” content=”技術評論社” />
<meta property=”fb:app_id” content=”185201618169441″ />
・・・・
Beautiful Soupの基本的な使い方
Beautiful Soup
は取得したHTMLデータの取得と解析を行う、スクレイピング用のライブラリです。
requests
で取得したデータから必要な情報を抽出するには、Beautiful Soup
を用いてHTMLを解析する必要があります。
記述方法は以下になります。
Yahooページを取得して、BeautifulSoupで解析して結果を表示します。
1 2 3 4 5 6 | import requests from bs4 import BeautifulSoup response = requests.get('https://gihyo.jp/book/list') soup = BeautifulSoup(response.text, 'html.parser') print(soup) |
出力結果
<html lang=”ja”>
<head prefix=”og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#”>
<meta content=”text/html; charset=utf-8″ http-equiv=”Content-Type”/>
<title>書籍一覧新刊|技術評論社</title>
<meta content=”” name=”description”/>
<meta content=”技術評論社,gihyo.jp,” name=”keywords”/>
<meta content=”width=device-width, initial-scale=1.0″ name=”viewport”/>
<meta content=”text/javascript” http-equiv=”Content-Script-Type”/>
<meta content=”text/css” http-equiv=”Content-Style-Type”/>
・・・・
response.text の内容がhtmlとしてBeautifulSoupのオブジェクトとして格納されます。この処理により情報を簡単に取得できるようになります。
BeautifulSoupでhtmlを解析することにより、タグ名やクラス属性、id属性を指定するだけで簡単に情報を取得できるようになります。
タグ、クラス、idによる要素の検索(find)
BeautifulSoupのfind()
メソッドを利用することで、任意のタグ属性、id属性を指定し要素を取得することが出来ます。
タグによる要素の検索
タグとはHTMLのソースに記載されている 「<」 と 「>」 で囲まれた部分になり、このタグを用いて文章の構造を表現しています。
タグについての詳細はこちらのページを参考にしてください。
最初のステップ!HTMLで覚えておきたい頻出タグ15選【初心者向け】現役エンジニアが紹介
find()
メソッドを利用して、ページのtitleタグを検索してみます。
1 2 3 4 | title = soup.find("title") print(title) # <title>書籍一覧新刊|技術評論社</title> |
このようにtitleタグの要素を取得することができます。
取得した結果はオブジェクトになっているため、テキストのみを取得したい場合は.text
プロパティでテキストを取得します。
1 2 | print(title.text) # 書籍一覧新刊|技術評論社 |
次にh2タグの要素を取得してみます。
1 2 3 4 | h2_item = soup.find("h2") print(h2_item) # <h2>新刊書籍一覧</h2> |
h2タグ要素は他にもありますが、find()
メソッドでは一番最初の要素だけを取得します。
全ての要素を取得するには、後で説明するfind_all()
メソッドを使用します。
※上図のようにブラウザでソースを表示するには、対象のページが表示されている状態でF12キーを押すことで、右側のウィンドウに表示する事ができます。(表示はGoogle Chromeの例)
クラスによる要素の検索
クラス名を指定して要素を取得する方法です。
記述方法は以下になります。
class
はPythonの予約後で使用できない為、class_
と書きます。
ここでは、ナビゲーションメニューのテキストを取得してみます。
対象の要素のクラス名を調べるために、ブラウザの開発者ツールを使用します。
F12で開発者ツールを開き、ツールウィンドウ左上の「ページ内の要素を選択して検査」のボタンをクリックします。
その後、ブラウザ上の要素を選択できる状態になるため、調べたい要素がハイライトされる場所でクリックします。
クリックすると、右側のウィンドウで要素のソースに移動するため、ここでクラス名を調べます。
find()
メソッドの引数にクラス名「main clearfix」を指定して要素を取得し、.text
でテキストを表示します。
1 2 3 4 5 6 7 8 9 10 | item = soup.find(class_="main clearfix") print(item.text) # 本を探す # 新刊書籍 # 雑誌 # 電脳会議 # gihyo.jp # 電子書籍 # 直販 |
idによる要素の検索
次にid名を指定して要素を取得します。
記述方法は以下になります。
以下の例では、id名が「secondary」の要素を取得して、テキストを表示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | item = soup.find(id="secondary") print(item.text) トピックス #『図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書』紙版10刷4万5,000部達成記念!最新AWSサービス一覧シート(PDF版)、ダウンロード配布開始! # イベント・キャンペーン 2022/2/17『リアルサイズ古生物図鑑 新生代編』がNIKKEIプラス1 何でもランキングで2位を獲 得! # 書評掲載 2022/2/15『「会社は無理ゲー」な人がノビノビ稼ぐ方法』著者、堀田孝治氏が登壇したイベントの模様が、logmiにてテキストレポートで全公開! # イベント・キャンペーン 2022/2/9『メイカーのための ねじのキホン』著者 門田和雄氏がおたくま経済新聞に取り上げられました # 発売告知 2022/2/92022年3月19日発売『メタバース進化論』、序論9,000文字+目次公開中! # 発売告知 2022/2/3 # すべてのトピックスはこちら # # 重要なお知らせ # # 2021年度 新型コロナウイルス感染防止に伴うオンライン授業への弊社書籍利用について # 2021/3/24 # すべての重要なお知らせはこちら |
全ての要素の検索(find_all)
先程のfind()
メソッドでは、同じタグ名が複数ある場合に一番初めの要素しか取得出来ませんでしたが、find_all()
メソッドを使用することで、すべての要素を取得することができます。
タグによる全ての要素の検索
find_all()
メソッドでタグ名を指定して全ての要素を取得する方法です。
以下の例では<h2>タグの全ての要素を取得して、テキスト内容を表示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 | for items in soup.find_all("h2"): print(items.text) # 新刊書籍一覧 # トピックス # 重要なお知らせ # 書籍案内 # 定期刊行物一覧 # 直販ストア # 電子書籍ストア # # メールでのお知らせ # このサイトについて |
指定したクラスのタグを全て検索
find_all()
の引数にクラスやidを追加することにより、指定したクラスやid属性を持つタグの要素のみを取得する事ができます。
記述方法は以下になります。
以下の例では新刊書籍一覧のリストの要素を全て取得して、テキスト内容を表示しています。
各リストのタグは<li>で、クラス名は「cleafix」で共通になっている為、これらをfind_all()
の引数に指定します。
1 2 | for item in soup.find_all("li", class_="clearfix"): print(item.text) |
find_all
で複数要素を取得し、for文で1要素ずつ取り出して、テキスト内容を出力しています。
・関連記事:繰り返し処理(for文)
出力結果は以下のようになります。
新時代を生き抜く越境思考~組織、肩書、場所、時間から自由になって成長する
沢渡あまね 著
2022年3月25日発売
定価2,420円(本体2,200円+税10%)
ゼロからはじめるシリーズ
ゼロからはじめるドコモ arrows We F-51B スマートガイド
技術評論社編集部 著
2022年3月12日発売
定価1,738円(本体1,580円+税10%)
・・・(以下省略)
取得した要素にはURLのリンクも含まれているため、合わせて取得してみます。
リンクは <a href=”url”>…</a>のように、<a>タグで表現されておりhref属性でリンク先を指定しています。
1 2 3 | for item in soup.find_all("li", class_="clearfix"): link = item.find("a").get('href')) print('https://gihyo.jp' + link) |
find_all()
で複数要素を取得し、for文で1要素ずつitem
として取り出します。
取り出した要素をさらにfind()
メソッドで<a>タグを検索し、.get("href")
でhref属性の値を取得しています。
取得したURLは不完全のため、リンクとして利用するために「https://gihyo.jp」を追加しています。
出力結果は以下のようになります。
https://gihyo.jp/book/2022/978-4-297-12713-8
https://gihyo.jp/book/2022/978-4-297-12564-6
https://gihyo.jp/book/2022/978-4-297-12683-4
https://gihyo.jp/book/2022/978-4-297-12639-1
https://gihyo.jp/book/2022/978-4-297-12613-1
https://gihyo.jp/book/2022/978-4-297-12605-6
https://gihyo.jp/book/2022/978-4-297-12709-1
https://gihyo.jp/book/2022/978-4-297-12617-9
https://gihyo.jp/book/2022/978-4-297-12609-4
https://gihyo.jp/book/2022/978-4-297-12643-8
https://gihyo.jp/book/2022/978-4-297-12663-6
https://gihyo.jp/book/2022/978-4-297-12588-2
https://gihyo.jp/book/2022/978-4-297-12659-9
https://gihyo.jp/book/2022/978-4-297-12649-0
https://gihyo.jp/book/2022/978-4-297-12455-7
https://gihyo.jp/book/2022/978-4-297-12601-8
https://gihyo.jp/book/2022/978-4-297-12726-8
https://gihyo.jp/magazine/wdpress/archive/2022/vol127
https://gihyo.jp/book/2022/978-4-297-12578-3
https://gihyo.jp/book/2022/978-4-297-12633-9
https://gihyo.jp/book/2022/978-4-297-12599-8
https://gihyo.jp/book/2022/978-4-297-12597-4
https://gihyo.jp/book/2022/978-4-297-12631-5
https://gihyo.jp/book/2022/978-4-297-12724-4
PythonでWebスクレイピングを行う方法を解説しました。