リクエストとPython3で美しいスープを使用してWebデータを操作する方法

提供:Dev Guides
移動先:案内検索

序章

Webは、私たちが読んで理解できるよりも多くのデータを提供してくれるので、その情報を理解するために、プログラムでその情報を処理したいことがよくあります。 そのデータは、.csvまたはコンマ区切りの値ファイルを介して、またはAPI(アプリケーションプログラミングインターフェイス)を介して、Webサイト作成者から提供される場合があります。 また、自分でWebからテキストを収集する必要がある場合もあります。

このチュートリアルでは、RequestsおよびBeautifulSoup Pythonパッケージを使用して、Webページのデータを利用する方法について説明します。 Requestsモジュールを使用するとPythonプログラムをWebサービスと統合できますが、BeautifulSoupモジュールは画面のスクレイピングをすばやく実行できるように設計されています。 Pythonインタラクティブコンソールとこれら2つのライブラリを使用して、Webページを収集し、そこで利用可能なテキスト情報を操作する方法を説明します。

前提条件

このチュートリアルを完了するには、Python3の開発環境が必要です。 シリーズPython3のローカルプログラミング環境をインストールしてセットアップする方法またはPython3をインストールしてプログラミング環境をセットアップする方法から入手できるオペレーティングシステムの適切なガイドに従うことができます。 Ubuntu20.04サーバーで必要なものをすべて構成します。

さらに、次のことをよく理解しておく必要があります。

開発環境をセットアップし、これらのPythonプログラミングの概念を念頭に置いて、RequestsとBeautifulSoupの使用を開始しましょう。

リクエストのインストール

Python3プログラミング環境をアクティブ化することから始めましょう。 環境が配置されているディレクトリにいることを確認し、次のコマンドを実行します。

. my_env/bin/activate

Webページを操作するには、ページをリクエストする必要があります。 Requestsライブラリを使用すると、Pythonプログラム内で人間が読める形式でHTTPを利用できます。

プログラミング環境をアクティブにして、pipを使用してRequestsをインストールします。

pip install requests

Requestsライブラリのインストール中に、次の出力が表示されます。

OutputCollecting requests
  Downloading requests-2.26.0-py2.py3-none-any.whl (88kB)
    100% |████████████████████████████████| 92kB 3.1MB/s 
...
Installing collected packages: chardet, urllib3, certifi, idna, requests
Successfully installed certifi-2017.4.17 chardet-3.0.4 idna-2.5 requests-2.26.0 urllib3-1.21.1

Requestsが以前にインストールされていた場合は、ターミナルウィンドウから次のようなフィードバックを受け取ります。

OutputRequirement already satisfied
...

プログラミング環境にリクエストをインストールしたら、次のモジュールのインストールに進むことができます。

美しいスープをインストールする

Requestsで行ったのと同じように、pipを使用してBeautifulSoupをインストールします。 Beautiful Soup 4の現在のバージョンは、次のコマンドでインストールできます。

pip install beautifulsoup4

このコマンドを実行すると、次のような出力が表示されます。

OutputCollecting beautifulsoup4
  Downloading beautifulsoup4-4.10.0-py3-none-any.whl (97 kB)
     |████████████████████████████████| 97 kB 6.8 MB/s
Collecting soupsieve>1.2
  Downloading soupsieve-2.3.1-py3-none-any.whl (37 kB)
Installing collected packages: soupsieve, beautifulsoup4
Successfully installed beautifulsoup4-4.10.0 soupsieve-2.3.1

Beautiful SoupとRequestsの両方がインストールされたので、ライブラリを操作してWebサイトをスクレイプする方法の理解に進むことができます。

リクエストを含むWebページの収集

これから使用する2つのPythonライブラリがインストールされているので、基本的なWebページをステップスルーすることに慣れることができます。

まず、 Python InteractiveConsoleに移動しましょう。

python

ここから、Requestsモジュールをインポートして、サンプルWebページを収集できるようにします。

import requests

サンプルWebページのURL(以下)mockturtle.html変数urlに割り当てます。

url = 'https://assets.digitalocean.com/articles/eng_python/beautiful-soup/mockturtle.html'

次に、 request.get()メソッドを使用して、そのページのリクエストの結果を変数pageに割り当てることができます。 ページのURL(url変数に割り当てられた)をそのメソッドに渡します。

page = requests.get(url)

変数pageには、応答オブジェクトが割り当てられます。

>>> page
<Response [200]>
>>> 

上記のResponseオブジェクトは、角かっこで囲まれたstatus_codeプロパティ(この場合は200)を示しています。 この属性は明示的に呼び出すことができます。

>>> page.status_code
200
>>> 

返された200のコードは、ページが正常にダウンロードされたことを示しています。 番号2で始まるコードは通常成功を示し、4または5で始まるコードはエラーが発生したことを示します。 HTTPステータスコードの詳細については、W3Cのステータスコード定義を参照してください。

Webデータを操作するために、Webファイルのテキストベースのコンテンツにアクセスする必要があります。 サーバーの応答の内容は、page.text(または、応答にバイト単位でアクセスする場合はpage.content)で読み取ることができます。

page.text

ENTERを押すと、次の出力が表示されます。

Output'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n    
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n<html lang="en-US" 
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n<head>\n  <meta 
http-equiv="content-type" content="text/html; charset=us-ascii" />\n\n  <title>Turtle 
Soup</title>\n</head>\n\n<body>\n  <h1>Turtle Soup</h1>\n\n  <p class="verse" 
id="first">Beautiful Soup, so rich and green,<br />\n  Waiting in a hot tureen!<br />\n  Who for 
such dainties would not stoop?<br />\n  Soup of the evening, beautiful Soup!<br />\n  Soup of 
the evening, beautiful Soup!<br /></p>\n\n  <p class="chorus" id="second">Beau--ootiful 
Soo--oop!<br />\n  Beau--ootiful Soo--oop!<br />\n  Soo--oop of the e--e--evening,<br />\n  
Beautiful, beautiful Soup!<br /></p>\n\n  <p class="verse" id="third">Beautiful Soup! Who cares 
for fish,<br />\n  Game or any other dish?<br />\n  Who would not give all else for two<br />\n  
Pennyworth only of Beautiful Soup?<br />\n  Pennyworth only of beautiful Soup?<br /></p>\n\n  
<p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br />\n  Beau--ootiful Soo--oop!<br />\n  
Soo--oop of the e--e--evening,<br />\n  Beautiful, beauti--FUL SOUP!<br 
/></p>\n</body>\n</html>\n'
>>> 

ここでは、ページの全文がすべてのHTMLタグとともに印刷されていることがわかります。 ただし、間隔が狭いため読みづらいです。

次のセクションでは、Beautiful Soupモジュールを活用して、このテキストデータをより人間に優しい方法で操作できます。

美しいスープでページをステップスルー

Beautiful Soupライブラリは、解析されたHTMLおよびXMLドキュメント(閉じられていないタグまたはタグスープおよびその他の不正な形式のマークアップを含むドキュメントを含む)から解析ツリーを作成します。 この機能により、RequestsモジュールからのテキストよりもWebページのテキストが読みやすくなります。

まず、BeautifulSoupをPythonコンソールにインポートします。

from bs4 import BeautifulSoup

次に、モジュールを介してpage.textドキュメントを実行し、BeautifulSoupオブジェクト、つまり、Pythonの組み込みの実行から取得するこの解析済みページからの解析ツリーを取得します。 HTML上のhtml.parser。 構築されたオブジェクトは、mockturtle.htmlドキュメントをネストされたデータ構造として表します。 これは変数soupに割り当てられます。

soup = BeautifulSoup(page.text, 'html.parser')

ターミナルにページのコンテンツを表示するには、prettify()メソッドを使用してページを印刷し、BeautifulSoup解析ツリーを適切にフォーマットされたUnicode文字列に変換します。

print(soup.prettify())

これにより、各HTMLタグが独自の行にレンダリングされます。

Output<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
  <title>
   Turtle Soup
  </title>
 </head>
 <body>
  <h1>
   Turtle Soup
  </h1>
  <p class="verse" id="first">
   Beautiful Soup, so rich and green,
   <br/>
   Waiting in a hot tureen!
   <br/>
   Who for such dainties would not stoop?
   <br/>
   Soup of the evening, beautiful Soup!
 ...
</html>

上記の出力では、1行に1つのタグがあり、BeautifulSoupで使用されるツリースキーマのためにタグがネストされていることがわかります。

タグのインスタンスの検索

Beautiful Soupのfind_allメソッドを使用して、ページから1つのタグを抽出できます。 これにより、ドキュメント内の特定のタグのすべてのインスタンスが返されます。

soup.find_all('p')

オブジェクトでそのメソッドを実行すると、関連する<p>タグと、要求されたタグに含まれるすべてのタグ(ここでは改行タグ<br/>を含む)とともに曲の全文が返されます。

Output[<p class="verse" id="first">Beautiful Soup, so rich and green,<br/>
  Waiting in a hot tureen!<br/>
  Who for such dainties would not stoop?<br/>
  Soup of the evening, beautiful Soup!<br/>
  Soup of the evening, beautiful Soup!<br/></p>, <p class="chorus" id="second">Beau--ootiful Soo--oop!<br/>
...
  Beau--ootiful Soo--oop!<br/>
  Soo--oop of the e--e--evening,<br/>
  Beautiful, beauti--FUL SOUP!<br/></p>]

上記の出力では、データが角かっこ[ ]で囲まれていることがわかります。 これは、Pythonリストデータ型であることを意味します。

これはリストであるため、その中の特定のアイテム(たとえば、3番目の<p>要素)を呼び出し、get_text()メソッドを使用してそのタグ内からすべてのテキストを抽出できます。

soup.find_all('p')[2].get_text()

この場合、受け取る出力は3番目の<p>要素になります。

Output'Beautiful Soup! Who cares for fish,\n  Game or any other dish?\n  Who would not give all else for two\n  Pennyworth only of Beautiful Soup?\n  Pennyworth only of beautiful Soup?'

\nの改行は、上記の返される文字列にも表示されることに注意してください。

クラスとIDによるタグの検索

クラスやIDなどのCSSセレクターを参照するHTML要素は、BeautifulSoupを使用してWebデータを操作するときに確認するのに役立ちます。 find_all()メソッドを使用し、クラスとIDの文字列を引数として渡すことで、特定のクラスとIDをターゲットにできます。

まず、クラスchorusのすべてのインスタンスを見つけましょう。 Beautiful Soupでは、クラスの文字列をキーワード引数class_に割り当てます。

soup.find_all(class_='chorus')

上記の行を実行すると、次のリストが出力として表示されます。

Output[<p class="chorus" id="second">Beau--ootiful Soo--oop!<br/>
  Beau--ootiful Soo--oop!<br/>
  Soo--oop of the e--e--evening,<br/>
  Beautiful, beautiful Soup!<br/></p>, <p class="chorus" id="fourth">Beau--ootiful Soo--oop!<br/>
  Beau--ootiful Soo--oop!<br/>
  Soo--oop of the e--e--evening,<br/>
  Beautiful, beauti--FUL SOUP!<br/></p>]

chorusのクラスの2つの<p>タグ付きセクションが端末に印刷されました。

複数のタグに使用されている場合は、<p>タグ内でのみクラスchorusを検索するように指定することもできます。

soup.find_all('p', class_='chorus')

上記の行を実行すると、以前と同じ出力が生成されます。

また、Beautiful Soupを使用して、HTMLタグに関連付けられたIDをターゲットにすることもできます。 この場合、文字列'third'をキーワード引数idに割り当てます。

soup.find_all(id='third')

上記の行を実行すると、次の出力が表示されます。

Output[<p class="verse" id="third">Beautiful Soup! Who cares for fish,<br/>
  Game or any other dish?<br/>
  Who would not give all else for two<br/>
  Pennyworth only of Beautiful Soup?<br/>
  Pennyworth only of beautiful Soup?<br/></p>]

IDがthird<p>タグに関連付けられたテキストは、関連するタグとともに端末に印刷されます。

結論

このチュートリアルでは、PythonのRequestsモジュールを使用してWebページを取得し、Beautiful Soupを理解するために、そのWebページのテキストデータを予備的にスクレイピングする方法について説明しました。

ここから、チュートリアル美しいスープとPython 3でWebページをスクレイピングする方法に従って、Webから収集されたデータからCSVファイルを作成するWebスクレイピングプログラムの作成に進むことができます。