PythonでHTMLを解析してデータ収集してみる? スクレイピングが最初からわかる『Python 2年生』|翔泳社の本

PythonでHTMLを解析してデータ収集してみる? スクレイピングが最初からわかる『Python 2年生』

2020/05/18 07:00

 これからPythonを基礎から学びたい方におすすめの本が『Python 1年生』シリーズです。開発部門に配属されたばかりの新人社員や学生などプログラミングの経験がまったくない方でも読みやすく、ヤギ博士とフタバちゃんの掛け合いで解説が進んでいくのが特徴。今回はシリーズの『Python 2年生』から、主にWeb上のデータを収集・選別するスクレイピングの基本となるHTMLの解析を取り上げた「LESSON04 HTMLを解析してみよう」を抜粋して紹介します。Pythonをインストールしてからお楽しみください。

本記事は『Python 2年生 スクレイピングのしくみ 体験してわかる!会話でまなべる!』の「LESSON04 HTMLを解析してみよう」から抜粋したものです。掲載にあたり一部を編集しています。

より基本的な内容を解説した『Python 1年生 体験してわかる!会話でまなべる!プログラミングのしくみ』から読んでいただくと、さらにPythonやプログラミングを理解しやすくなります。
HTMLを解析してみよう
ヤギ博士

Beautiful Soupをインストール

 HTMLを簡単に解析できるライブラリがあります。それが「Beautiful Soup」です。外部ライブラリなので、以下の手順でインストールしましょう。

 Windowsにインストールするときは、コマンドプロンプトを使います。

pip install beautifulsoup4

 macOSにインストールするときは、ターミナルを使います。

pip3 install beautifulsoup4

Beautiful Soupで解析する

 Beautiful Soupを使うときは、まずライブラリをimportします。Beautiful Soupは、bs4というパッケージに入っているので「from bs4 import BeautifulSoup」と指定して使います。

 解析するには、まず1章でやったように、requestsでインターネットからWebページを取得します。次に、そのHTMLデータ(.content)を「BeautifulSoup( HTMLデータ, "html.parser")」に渡します。たったこれだけで解析が終わります。

HTML を解析する
from bs4 import BeautifulSoup    # importする
soup = BeautifulSoup(html.content, "html.parser")    # HTMLを解析する

 本書のために用意したWebページ「https://www.ymori.com/books/python2nen/test1.html」を読み込んで解析してみましょう。ちゃんと読み込まれたか、返ってきた値を表示してみましょう。

import requests
from bs4 import BeautifulSoup
# Webページを取得して解析する

load_url = "https://www.ymori.com/books/python2nen/test1.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# HTML全体を表示する
print(soup)
出力結果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Python2年生</title>
</head>
<body>
<h2>第1章 Pythonでデータをダウンロード</h2>
<ol>
<li>スクレイピングってなに?</li>
<li>Pythonをインストールしてみよう</li>
<li>requestsでアクセスしてみよう</li>
</ol>
</body>
</html>

 読み込んだHTMLがそのまま表示されているだけのように見えますが、これが解析したあとの状態です。ここからいろいろな要素を取り出していきます。

タグを探して表示する

 では、要素を探して取り出してみましょう。検索は簡単。「タグ名を指定するだけ」です。「soup.fi nd( "タグ名" )」と命令しましょう。これは、指定したタグの要素を1つ見つけて取り出す命令です。

書式:タグを探して要素を取り出す
要素 = soup.find("タグ名")
書式:タグを探して要素を取り出す

 titleタグ、h2タグ、liタグを検索して、表示してみましょう。

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://www.ymori.com/books/python2nen/test1.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# title、h2、liタグを検索して表示する
print(soup.find("title"))    # タグを検索して表示
print(soup.find("h2"))
print(soup.find("li"))
出力結果
<title>Python2年生</title>
<h2>第1章 Pythonでデータをダウンロード</h2>
<li>スクレイピングってなに?</li>

 要素が3つ表示されましたね。でもこれだとタグつきの状態なので、ここから文字列だけを取り出しましょう。文字列を取り出すには最後に「.text」をつけます。

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://www.ymori.com/books/python2nen/test1.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# title、h2、liタグを検索して、その文字列を表示する
print(soup.find("title").text)    # .textを追加
print(soup.find("h2").text)
print(soup.find("li").text)
出力結果
Python2年生
第1章 Pythonでデータをダウンロード
スクレイピングってなに?

 これで、Webページから指定したタグの文字列を取り出すことができました。

すべてのタグを探して表示する

 .fi nd( "タグ名" )を使うと、要素を見つけることができますが、取得できるのは見つかった最初の1つだけです。一般的なWebページには要素はもっとたくさんあります。そこで、次は「すべての要素」を探してみましょう。

 テスト用として、要素を少し増やした「test2.html」を用意しました。

test2.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Python2年生</title>
    </head>
    <body>
        <div id="chap1">
            <h2>第1章 Pythonでデータをダウンロード</h2>
            <ol>
                <li>スクレイピングってなに?</li>
                <li>Pythonをインストールしてみよう</li>
                <li>Requestsでアクセスしてみよう</li>
            </ol>
        </div>
        <div id="chap2">
            <h2>第2章 HTMLを解析しよう</h2>
            <ol>
                <li>HTMLを解析してみよう</li>
                <li>ニュースの最新記事一覧を取得してみよう</li>
                <li>リンク一覧をファイルに書き出そう</li>
                <li>画像を一括ダウンロードしよう</li>
            </ol>
        </div>

        <a href="https://www.ymori.com/books/python2nen/test1.html">リンク1</a>
        <a href="./test3.html">リンク2</a><br/>
        <img src="https://www.ymori.com/books/python2nen/sample1.png">
        <img src="./sample2.png">
        <img src="./sample3.png">
    </body>
</html>

 この「test2.html」はWeb上に用意してあり、以下のような表示になります。このHTMLをスクレイピングしてみましょう。

Python2年生のテスト用ページ
https://www.ymori.com/books/python2nen/test2.html

test2.html

 すべての要素を探すときは、「soup.fi nd_all( "タグ名" )」を使います。タグをすべて検索して、見つかった要素をリスト形式で返します。リストの中身はfor文を使えば、1つずつ取り出せます。

書式:すべてのタグを探して要素を取り出す
要素のリスト = soup.find_all("タグ名")
書式:すべてのタグを探して要素を取り出す

 それでは、ページのすべてのliタグを探して、表示しましょう。

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://www.ymori.com/books/python2nen/test2.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# すべてのliタグを検索して、その文字列を表示する
for element in soup.find_all("li"):    # すべてのliタグを検索して表示
    print(element.text)
出力結果
スクレイピングってなに?
Pythonをインストールしてみよう
Requestsでアクセスしてみよう
HTMLを解析してみよう
ニュースの最新記事一覧を取得してみよう
リンク一覧をファイルに書き出そう
画像を一括ダウンロードしよう
ページの中のすべてのliタグの文字列が表示されたね。

idやclassで検索範囲を絞り込む

 Webページはたくさんの要素でできています。このとき「どの要素なのか」を区別しやすくするために、「id属性」や「class属性」で固有の名前をつけることができます。

 例えば「test2.html」では、1章に「<div id="chap1">」、2章に「<div id="chap2">」とid属性に固有の名前をつけて区別しています。

id属性、class属性

 Beautiful Soupでは、この「id属性」や「class属性」の名前を使い、範囲を絞り込んで検索することができます。

書式:id で探して要素を取り出す
要素 = soup.find(id="id名")
書式:class で探して要素を取り出す
要素 = soup.find(class_="class名")
※「class」はPythonの予約語でそのままでは使えないので「class_」と書きます。
soup.find(id=

MEMO id属性とclass属性

id属性とclass属性は、「要素を他の要素と区別するもの」としては似ていますが、以下のような違いがあります。

id属性
ページ内に1つしかない要素に使います。ページ内に1つしかないものにつける名前なので、1つのHTMLファイル内に同じ名前は1つしか使えません。

class属性
同じデザインの要素に使います。ページ内に同じデザインの要素が並ぶことはあるので、1つのHTMLファイル内に同じ名前を複数使えます。1つのHTMLファイル内に1つしかない場合もあります。

 まず、「2章の要素」を取得してみましょう。「<div id="chap2">」なので、idが「chap2」の要素を検索します。

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://www.ymori.com/books/python2nen/test2.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# IDで検索して、そのタグの中身を表示する
chap2 = soup.find(id="chap2")    # idが「chap2」の範囲の要素を表示
print(chap2)
出力結果
<div id="chap2">
<h2>第2章 HTMLを解析しよう</h2>
<ol>
<li>HTMLを解析してみよう</li>
<li>ニュースの最新記事一覧を取得してみよう</li>
<li>リンク一覧をファイルに書き出そう</li>
<li>画像を一括ダウンロードしよう</li>
</ol>
</div>

 2章の要素が取得できましたね。これで検索範囲を絞り込むことができました。今度は、この要素に対してliタグをすべて探してみましょう。

import requests
from bs4 import BeautifulSoup

# Webページを取得して解析する
load_url = "https://www.ymori.com/books/python2nen/test2.html"
html = requests.get(load_url)
soup = BeautifulSoup(html.content, "html.parser")

# IDで検索し、その中のすべてのliタグを検索して表示する
chap2 = soup.find(id="chap2")    # idが「chap2」を検索
for element in chap2.find_all("li"):    # その中のliタグの文字列を表示
    print(element.text)
出力結果
HTMLを解析してみよう
ニュースの最新記事一覧を取得してみよう
リンク一覧をファイルに書き出そう
画像を一括ダウンロードしよう

 これで「2章の項目だけをすべて取り出す」ことができました。

Python 2年生 スクレイピングのしくみ 体験してわかる!会話でまなべる!

Python 2年生
【Amazon】  【SEshop】  【その他】

「はじめに」より

 この本は、Python初心者の方がやさしく次のステップへ進むための本です。

 Pythonは「Webへのアクセス」や「データ処理」が得意な言語です。だから、「機械学習」や「ビッグデータの分析」によく使われているのですが、そんな大げさなものではなく、「自分のちょっとした調べもの」に使ってもいいのです。

 気になるニュースを調べたり、地元のお店の情報を調べたり、自宅の明日の天気を調べたり、「Pythonを自分の身の回りの調べものに使ってみる」のなら、やさしく次へ進めると思いませんか。うまくできれば、役に立つプログラムも作れます。

Python 1年生 体験してわかる!会話でまなべる!プログラミングのしくみ

Python 1年生
【Amazon】  【SEshop】  【その他】

「はじめに」より

 最近、Pythonはとても人気があります。特に人工知能の分野で注目を集めています。人工知能は、家電やロボットなど私たちの生活の中にも入ってきています。みなさんがPythonに興味を持たれたのも、人工知能に関心があったからではないでしょうか。

 書店に行くと、機械学習やディープラーニングなど人工知能系の書籍がたくさん並んでいます。ですが多くの本は専門的で難しそうですし、どうやらPythonというプログラミング言語も勉強しないといけないようです。いずれはちゃんと理解していきたいけれど、最初はまずどんな感じなのかやさしく体験してみたい、と思っておられる方はたくさんいるのではないでしょうか。

 この本は、そうしたPython初心者の方のための本です。やさしいヤギ博士と好奇心でいっぱいのフタバちゃんと一緒に、Python言語を体験していきましょう。