[Python] requests/beautifulsoup でスクレイピング

requests/beautifulsoup/lxml のコンビでスクレイピングを行ってみます。

Requests

Requests: HTTP for Humans™

Python で一番使いやすいHTMLライブライです。

下記コマンドでインストールします。

pip install requests

BeautifulSoup

Beautiful Soup Documentation

HTMLの構造解析、整形、修正等を行うライブラリです。

下記コマンドでインストールします。

pip install bs4

HTMLの解析に、デフォルトでは、下記のPythonの標準ライブラリのHTMLパーサーを使います。

html.parser— HTML および XHTML のシンプルなパーサー

ここでは、lxmlという標準のパーサーより速度面で有利なパーサーを使用します。

lxml

lxml – XML and HTML with Python

htmlパーサーです。

c言語で書かれているので、デフォルトのhtmlパーサーより高速です。

以下のコマンドでインストールします。

pip install lxml

モジュールのインポート

インタラクティブモードで進めます。

>>> import requests
>>> from bs4 import BeautifulSoup

ページの取得

requestsを使って、googleのページを取得します。

result = requests.get('https://www.google.com/')

無事に取得できたかステータスコードを見てみます。

HTTPステータスコード

>>> result.status_code
200

html ヘッダーを見てみます。

>>> result.headers
{'Date': 'Wed, 26 Jun 2019 08:54:35 GMT', 'Expires': '-1', 'Cache-Control': 'private, max-age=0', 'Content-Type': 'text/html; charset=ISO-8859-1', 'P3P': 'CP="This is not a P3P policy! See g.co/p3phelp for more info."', 'Content-Encoding': 'gzip', 'Server': 'gws', 'X-XSS-Protection': '0', 'X-Frame-Options': 'SAMEORIGIN', 'Set-Cookie': '1P_JAR=2019-06-26-08; expires=Fri, 26-Jul-2019 08:54:35 GMT; path=/; domain=.google.com, NID=186=el1-wc2voSknGeb7VdilUneeRI5zExxY_b0wyA7xb2LXLvVTPay497LEUQvLLJRghA_RiDwSAZ6ujeKtV-tLRiGgbj6q9j-_3tnNAaR8G1684HfeoLmMD3_TQNbQz3QhBTnMR-Uk2fTXHReoZ6A8uZ80bW17EqfAzDV1deTkxgs; expires=Thu, 26-Dec-2019 08:54:35 GMT; path=/; domain=.google.com; HttpOnly', 'Alt-Svc': 'quic=":443"; ma=2592000; v="46,44,43,39"', 'Transfer-Encoding': 'chunked'}

取得したhtmlのソースを確認します。

>>> src = result.content
>>> src
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja">
# 省略
</body></html>'

取得できています。

ページの解析

beautifulsoupを使ってhtmlの解析を行います。

beautifulsoupオブジェクトとして、htmlソースを読み込みます。

>>> soup = BeautifulSoup(src, 'lxml')

ソースが読みやすいように整形して表示します。

>>> soup.prettify()
<!DOCTYPE html>
<html itemscope="" itemtype="http://schema.org/WebPage" lang="ja">
 <head>
 <meta content="世界中のあらゆる情報を検索するためのツールを提供しています。さまざまな検索機能を活用して、お探しの情報を見つけてください。" name="description"/>
# 省略
  </script>
 </body>
</html>

最初に出てくるpタグを取得します。

>>> soup.p
<p style="color:#767676;font-size:8pt">© 2019 - <a href="/intl/ja/policies/privacy/">プライバシー</a> - <a href="/intl/ja/policies/terms/">規約</a></p>

aタグを全て、リストで取得します。

>>> tag = soup.find_all('a')
>>> tag
[<a class="gb1" href="https://www.google.co.jp/imghp?hl=ja&tab=wi">画像</a>, 
# 省略
<a href="/intl/ja/policies/terms/">規約</a>]

2つ目のaタグを取得し、そのclass属性を取得してみます。

続けて、全ての属性を取得してみます。

また、テキストを取得します。

>>> tag = soup.find_all('a')[1]
>>> tag
<a class="gb1" href="https://maps.google.co.jp/maps?hl=ja&tab=wl">マップ</a>
>>> tag['class']
['gb1']
>>> tag.attrs
{'class': ['gb1'], 'href': 'https://maps.google.co.jp/maps?hl=ja&tab=wl'}
>>> tag.string
'マップ'

全てのリンクを取得して、その中で’Google について’というテキストを持つリンクを抽出します。

>>> links = soup.find_all('a')
>>> for link in links:
...     if 'Google について' in link.text:
...         print(link)
...         print(link.attrs['href'])
...
<a href="/intl/ja/about.html">Google について</a>
/intl/ja/about.html

無事に取得できています。

その他

googleで検索して結果を取得してみるつもりでしたが、robots.txtで許可されていないので、やめておきます。

Webスクレイピングする際のルールとPythonによる規約の読み込み