【python】BeautifulSoupライブラリを使ったWebスクレイピングの実装方法

この記事ではBeautifulSoupライブラリを使ってWeb上のデータをスクレイピングする方法を具体的に解説します。

サンプルコードをコピペしながら、サクサク処理を試せますのでぜひ活用してみてください。

目次

Webスクレイピングとは

Webスクレイピングとは、Web上に公開されている任意の情報を抽出できるコンピュータソフトウェア技術を指します。

  • 画像サイトから画像データだけを抽出
  • ニュースサイトから特定のキーワードが含まれる記事だけを抽出
  • ECサイトから最安値の販売元情報を抽出
  • Google検索の検索順位を自動収集
  • 予約サイトの空き情報を監視

など、さまざまな場面で活用できます。

大量のデータを扱う業種や個人にとってはとても便利な技術です。

また、プログラムコードで一度スクレイピングの仕組みを構築すれば半永久的にデータ収集を自動化できます。

昨今、機械学習やビッグデータ活用が話題となっていることから、情報・データの価値はますます高まっていくことが予想されます。

より効率的に膨大な量のデータを収集できるという点でWebスクレイピングはとても有用です。

ぜひマスターしてみてください。

pythonのスクレイピングライブラリ

pythonではよく使われるWebスクレイピングを可能にする代表的なライブラリが2つあります。

本記事

BeautifulSoup

  • requestsライブラリでのデータ取得と組み合わせて使用
  • html, xmlからのデータ抽出が可能

Selenium

  • ChromeDriverと組み合わせて使用
  • ライブラリひとつでデータ取得、抽出が可能

この記事ではBeautifulSoupライブラリを使った方法にフォーカスして、Webスクレイピングの実践方法を紹介します。


ライブラリのインストール

まず初めにpythonの実行環境にスクレイピング実装に必要なライブラリをインストールします。

ターミナル(mac)もしくはコマンドプロンプト(Windows)で下記を実行します。

pip install requests
pip install beautifulsoup4

最終行に「Successfully installed 〜〜〜」と表示されていればインストールは成功です。

それでは、pythonのサンプルコードと一緒にWebスクレイピングを実践していきましょう。


(実装例) ニュースサイトのトピック一覧からURLを抽出

Webスクレイピングの実装例として、「Yahoo! JAPAN」のトップページからニューストピックス一覧の記事URLを抽出してみます。

以下、サンプルコードです。

import requests
from bs4 import BeautifulSoup

# Yahoo! JAPANのurl
url = "https://www.yahoo.co.jp/"

# requestsライブラリのgetメソッドで特定urlにアクセス
response = requests.get(url)

# アクセスしたページのHTML構文を解析(パース)
bs = BeautifulSoup(response.text, "html.parser")

# html上のニューストピックス一覧のcssセレクターを指定して抽出(リスト型で取得)
news_topics = bs.select("#tabpanelTopics1 > div > div._2jjSS8r_I9Zd6O9NFJtDN- > ul")

# 取得されたhtmlから「aタグ」の情報だけを抽出(リスト型で取得)
news_list = news_topics[0].find_all("a")
for news in news_list:
    # aタグのテキスト、urlリンクを表示
    print(news.text, news.attrs["href"])

サンプルコードの実行結果は以下の通りです。

# 出力結果
都コロナ入院患者 先週から倍増 https://news.yahoo.co.jp/pickup/6413282
コロナ飲み薬 大阪など重点配送NEW https://news.yahoo.co.jp/pickup/6413285
日本兵 横井庄一さんカルテ発見 https://news.yahoo.co.jp/pickup/6413281
香港大 天安門追悼像を撤去NEW https://news.yahoo.co.jp/pickup/6413265
マックポテト 駆け込み客が殺到 https://news.yahoo.co.jp/pickup/6413279
坂本花織、圧巻の演技でSP首位NEW https://news.yahoo.co.jp/pickup/6413283
堤幸彦氏 映画の酷評で自信喪失NEW https://news.yahoo.co.jp/pickup/6413286
はじめしゃちょー 登録1000万人 https://news.yahoo.co.jp/pickup/6413278
Yahoo! JAPANのニューストピックス一覧

ニューストピックス一覧の記事タイトルとURLが取得できていることがわかります。

BeautifulSoupライブラリの使い方

ここからはBeautifulSoupライブラリの具体的な使い方を具体的に紹介していきます。

ご自身でオリジナルのWebスクレイピングを実践してみてください。


Webページにアクセス

Webスクレイピングの最初のステップでは、BeautifulSoupライブラリではなくrequestsライブラリが担います。

まずはじめに下記を実行してpython上でWebサイトにアクセスします。

import requests
from bs4 import BeautifulSoup

# WebサイトののURL(ここではYahoo! JAPANのURL)
url = "https://www.yahoo.co.jp/"

# requestsライブラリのgetメソッドで特定urlにアクセス
response = requests.get(url)

変数responseアクセス先のWebサイト情報が格納されています。変数responseの中身を確認してみましょう。

print(response)
# 出力結果
<Response [200]>

変数responseをそのまま表示するとアクセス成否しか出力されません。(200はアクセス成功)


以下のようにしてアクセス先のWeb情報を確認できます。

print(response.content)

右図のようにWeb上のhtml情報は非常に膨大です。

これを自分の力で読み解いて処理を書くのは大変です。

pythonにはWeb情報を解析する機能が備わっています。

出力結果

Web上のHTML情報を解析

Webサイトにアクセスした後、WebサイトのHTML情報をpythonで解析(パース)する必要があります。

pythonには"html.parser"という解析機能が標準搭載されているためこちらを使用します。

# アクセス先WebサイトのHTML構文を解析(パース)
bs = BeautifulSoup(response.content, "html.parser")

ここでBeautifulSoupライブラリを使用します。

BeautifulSoup()モジュールの第1引数にアクセス先のHTML情報を指定し、第2引数で"html.parser"と解析機能を指定します。

変数bsに解析結果が格納されており、ここからさまざまな方法でWeb情報を抽出することができます。


cssセレクタから抽出

Web情報の抽出でおすすめなのが、cssセレクタを指定する方法です。

Web上のhtml情報は複雑な階層構造となっており特定の情報を探すのがとても難しくなっています。

しかしブラウザの機能からcssセレクタを簡単に見つけて、データ抽出に指定することができます。


以下ではGoogle Chromeを使ったcssセレクタの探し方をご紹介します。

Google Chromeでアクセス先のWebサイトを開き、キーボードの「F12キー」を押すと下図の検証ツールが開きます。

左上のマークをクリックして、選択ツールを起動します。


選択ツールで任意の箇所にカーソルを合わせて検証ツール内でcssセレクタをコピーできます。

コピーしたcssセレクタを用いてBeautifulSoupライブラリのselect()メソッドを適用します。

# コピーしたcssセレクタ
css_selector = "#tabpanelTopics1 > div > div._2jjSS8r_I9Zd6O9NFJtDN- > ul"

# 指定したcssセレクタの情報を抽出
bs_selector = bs.select(css_selector)

変数bs_selectorにはhtml情報の中の指定したcssセレクタのhtml情報のみがリスト型で格納されています。

以上のようにして、cssセレクタから任意の情報を抽出することができました。


htmlタグ名から抽出

他にもhtml情報の抽出方法があり、htmlタグ名から抽出することができます。

BeautifulSoupライブラリのfind()メソッドもしくはfind_all()メソッドを使用します。

find()メソッド

・指定したhtmlタグの先頭を抽出

# 先頭のaタグを抽出
a_tag = bs_selector[0].find("a")
print(a_tag)
# 出力結果
<a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:1;tpid:6413368;imgsize:s;cmt_num:799" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:1;tpid:6413368;imgsize:s;cmt_num:799" href="https://news.yahoo.co.jp/pickup/6413368"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">厚労省、コロナ飲み薬初承認</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>

find_all()メソッド

・指定したhtmlタグをすべて抽出

# すべてのaタグを抽出
a_all = bs_selector[0].find_all("a")
print(a_all)
# 出力結果
[<a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:1;tpid:6413368;imgsize:s;cmt_num:799" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:1;tpid:6413368;imgsize:s;cmt_num:799" href="https://news.yahoo.co.jp/pickup/6413368"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">厚労省、コロナ飲み薬初承認</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:2;tpid:6413356;imgsize:s;cmt_num:122" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:2;tpid:6413356;imgsize:s;cmt_num:122" href="https://news.yahoo.co.jp/pickup/6413356"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">家族らからの高齢者虐待 最多に</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:3;tpid:6413362;imgsize:s;cmt_num:365" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:3;tpid:6413362;imgsize:s;cmt_num:365" href="https://news.yahoo.co.jp/pickup/6413362"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span></h1></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:4;tpid:6413360;imgsize:s;cmt_num:0" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:4;tpid:6413360;imgsize:s;cmt_num:0" href="https://news.yahoo.co.jp/pickup/6413360"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">車の尿素水不足 製造現場に懸念</span></h1></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:5;tpid:6413366;imgsize:s;cmt_num:30" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:5;tpid:6413366;imgsize:s;cmt_num:30" href="https://news.yahoo.co.jp/pickup/6413366"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">iPhoneの故人アカ管理機能とは</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:6;tpid:6413320;imgsize:s;cmt_num:283" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:6;tpid:6413320;imgsize:s;cmt_num:283" href="https://news.yahoo.co.jp/pickup/6413320"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">全身17m超か 米で魚竜化石発見</span></h1></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:7;tpid:6413350;imgsize:s;cmt_num:0" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:7;tpid:6413350;imgsize:s;cmt_num:0" href="https://news.yahoo.co.jp/pickup/6413350"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">速報 全日本フィギュア男子SP</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2kuTmc13t1KkhU9h4mqeek" style="width:30px;height:12px">LIVE</span></span></div></div></a>,
 <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:8;tpid:6413367;imgsize:s;cmt_num:0" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:8;tpid:6413367;imgsize:s;cmt_num:0" href="https://news.yahoo.co.jp/pickup/6413367"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ジャニーズ頼り脱却? 紅白変化</span></h1></div></div></a>]

find_all()メソッドでは抽出結果をリスト型で取得します。

実装例のトピック記事一覧のURL取得ではfind_all()を使用しています。


属性名から抽出

htmlの属性名の代表的なものとしてclassやid、nameなどががあります。

これらの属性名を指定してhtml情報を抽出することができます。


class属性から抽出

下記のHTMLサンプルを見てみると、aタグの中にclass="xxxxxxx"と属性名が指定されたhtml情報が確認できます。

<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">首相 帰省や旅行は慎重に検討を</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">小中学生の男子体力 過去最低に</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ユニクロのセルフレジ訴訟 和解</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">「川の上の民家」11棟、撤去へ</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">バングラで船炎上 500人搭乗か</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">羽生 SP首位「今季世界最高点」</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ハラミちゃんの紅白取りやめか</span>

BeautifulSoupライブラリのfind()メソッドもしくはfind_all()メソッドを用いて、

html情報の中から特定の属性名の情報を抽出してみましょう。


html = """
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" href="https://news.yahoo.co.jp/pickup/6413378"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">首相 帰省や旅行は慎重に検討を</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" href="https://news.yahoo.co.jp/pickup/6413362"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" href="https://news.yahoo.co.jp/pickup/6413373"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">小中学生の男子体力 過去最低に</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" href="https://news.yahoo.co.jp/pickup/6413377"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ユニクロのセルフレジ訴訟 和解</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" href="https://news.yahoo.co.jp/pickup/6413374"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">「川の上の民家」11棟、撤去へ</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" href="https://news.yahoo.co.jp/pickup/6413370"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">バングラで船炎上 500人搭乗か</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" href="https://news.yahoo.co.jp/pickup/6413379"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">羽生 SP首位「今季世界最高点」</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" href="https://news.yahoo.co.jp/pickup/6413310"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ハラミちゃんの紅白取りやめか</span></h1></div></div></a>
"""
bs = BeautifulSoup(html, "html.parser")
# aタグ情報をすべて抽出
a_tag = bs.find_all("a")

# class="fQMqQTGJTbIMxjQwZA2zk"の情報を抽出
for tag in a_tag:
    class_data = tag.find(class_ = "fQMqQTGJTbIMxjQwZA2zk")
    print(class_data)
# 出力結果
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">首相 帰省や旅行は慎重に検討を</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">小中学生の男子体力 過去最低に</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ユニクロのセルフレジ訴訟 和解</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">「川の上の民家」11棟、撤去へ</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">バングラで船炎上 500人搭乗か</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">羽生 SP首位「今季世界最高点」</span>
<span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ハラミちゃんの紅白取りやめか</span>

find()もしくはfind_all()メソッドで属性名から抽出する際には注意点があります。

注意点

属性名classを指定するときはclass_=”xxxxx”で指定する。(classの後ろにアンダースコアを付ける)

# OK
find(class_ = "xxxxx")
# NG エラー
find(class = "xxxxx")

find()メソッドにclassという引数名はありません。

classはpythonにおける予約語なので、引数名として使われていません。


id属性から抽出

id属性の抽出も同様にfind()メソッドもしくはfind_all()メソッドを適用できます。

# id="yyyyy"の情報の先頭を抽出する場合
id_data = sample_html.find(id = "yyyyy")
# id="yyyyy"の情報すべてを抽出する場合
id_all = sample_html.find_all(id = "yyyyy")

タグ内のhref属性値を取得

主にURLリンクが含まれるaタグのhref属性値を取得することができます。

get()メソッドを用いて、href属性値(urlリンク)を抽出します。

html = """
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" href="https://news.yahoo.co.jp/pickup/6413378"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">首相 帰省や旅行は慎重に検討を</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" href="https://news.yahoo.co.jp/pickup/6413362"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" href="https://news.yahoo.co.jp/pickup/6413373"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">小中学生の男子体力 過去最低に</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" href="https://news.yahoo.co.jp/pickup/6413377"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ユニクロのセルフレジ訴訟 和解</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" href="https://news.yahoo.co.jp/pickup/6413374"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">「川の上の民家」11棟、撤去へ</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" href="https://news.yahoo.co.jp/pickup/6413370"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">バングラで船炎上 500人搭乗か</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" href="https://news.yahoo.co.jp/pickup/6413379"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">羽生 SP首位「今季世界最高点」</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" href="https://news.yahoo.co.jp/pickup/6413310"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ハラミちゃんの紅白取りやめか</span></h1></div></div></a>
"""
bs = BeautifulSoup(html, "html.parser")
# aタグ情報をすべて抽出
a_tag = bs.find_all("a")

# href属性値の情報を抽出
for tag in a_tag:
    url = tag.get("href")
    print(url)
# 出力結果
https://news.yahoo.co.jp/pickup/6413378
https://news.yahoo.co.jp/pickup/6413362
https://news.yahoo.co.jp/pickup/6413373
https://news.yahoo.co.jp/pickup/6413377
https://news.yahoo.co.jp/pickup/6413374
https://news.yahoo.co.jp/pickup/6413370
https://news.yahoo.co.jp/pickup/6413379
https://news.yahoo.co.jp/pickup/6413310

タグ内のテキストを抽出

タグ情報を取得した後にタグに含まれるテキストを抽出することができます。

.textを用いてタグに囲まれたテキストを抽出します。

html = """
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:1;tpid:6413378;imgsize:s;cmt_num:1058" href="https://news.yahoo.co.jp/pickup/6413378"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">首相 帰省や旅行は慎重に検討を</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:2;tpid:6413362;imgsize:s;cmt_num:687" href="https://news.yahoo.co.jp/pickup/6413362"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">大雪の恐れ 太平洋側も積雪か</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:3;tpid:6413373;imgsize:s;cmt_num:338" href="https://news.yahoo.co.jp/pickup/6413373"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">小中学生の男子体力 過去最低に</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:4;tpid:6413377;imgsize:s;cmt_num:535" href="https://news.yahoo.co.jp/pickup/6413377"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ユニクロのセルフレジ訴訟 和解</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:5;tpid:6413374;imgsize:s;cmt_num:435" href="https://news.yahoo.co.jp/pickup/6413374"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">「川の上の民家」11棟、撤去へ</span></h1></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:6;tpid:6413370;imgsize:s;cmt_num:70" href="https://news.yahoo.co.jp/pickup/6413370"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">バングラで船炎上 500人搭乗か</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:7;tpid:6413379;imgsize:s;cmt_num:182" href="https://news.yahoo.co.jp/pickup/6413379"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">羽生 SP首位「今季世界最高点」</span></h1><span class="_2obRU_TgAxzHaYqOXrZYlv"><span class="h4yLXygiSc5wwNlJOQEdz _1dr5aVDbNPF63JCS2bJhij _2M3AyDfFaeJl3Uo7lUPMAp" style="width:30px;height:12px">NEW</span></span></div></div></a>,
    <a class="yMWCYupQNdgppL-NV6sMi _3sAlKGsIBCxTUbNi86oSjt" data-cl-params="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" data-ual-gotocontent="true" data-ylk="rsec:tpto;slk:title;pos:8;tpid:6413310;imgsize:s;cmt_num:5440" href="https://news.yahoo.co.jp/pickup/6413310"><div class="_2cXD1uC4eaOih4-zkRgqjU"><div class="TRuzXRRZHRqbqgLUCCco9"><h1 class="_3cl937Zpn1ce8mDKd5kp7u"><span class="fQMqQTGJTbIMxjQwZA2zk _3tGRl6x9iIWRiFTkKl3kcR">ハラミちゃんの紅白取りやめか</span></h1></div></div></a>
"""
bs = BeautifulSoup(html, "html.parser")
# aタグ情報をすべて抽出
a_tag = bs.find_all("a")

# aタグ内のテキストを抽出
for tag in a_tag:
    print(tag.text)
# 出力結果
首相 帰省や旅行は慎重に検討をNEW
大雪の恐れ 太平洋側も積雪か
小中学生の男子体力 過去最低にNEW
ユニクロのセルフレジ訴訟 和解
「川の上の民家」11棟、撤去へ
バングラで船炎上 500人搭乗かNEW
羽生 SP首位「今季世界最高点」NEW
ハラミちゃんの紅白取りやめか

まとめ

今回はBeautifulSoupライブラリを用いたWebスクレイピングの方法を具体的に紹介しました。

ぜひご自身オリジナルのWebスクレイピングを実践してみましょう。

他にもPythonで役立つおすすめの記事がありますので、参考にしてみてください。

よかったらシェアしてね!
目次