見出し画像

【第1回 Python Beautiful Soup】Beautiful Soupでスクレイピングを使ってアマゾン商品のタイトルを抽出してみた。

こんにちは(@t_kun_kamakiri

前回は「selemium」を使ってWeb上のデータを抽出するというのをやりました。

今回は別のPythonのライブラリを使ってスクレイピングで遊んでみたいと思います。

自身の勉強ログとして書いています。

【Pythonの使用環境】
Google Collaboratory

Google CollaboratoryならGoogleアカウントがあればOSによらずにPythonが使えて便利ですよね。

必要な外部ライブラリのインストール

2つの外部ライブラリをインストールします。

●Beautiful Soup
●requests

Beautiful Soupは、HTMLやXMLのファイルからデータを抽出(スクレイピング)するためのPythonライブラリです。

Requestsは指定のURLからサイトを開くためのPython HTTPライブラリです。

まずは、Beautifulsoupをインストールして使えるようにしましょう。
Google Collaboratoryでは以下のように「!」を付けるとスクリプトとして認識されますので、

!pip install beautifulsoup4

と打てばBeautifulsoupがインストールされます。

例えば「Beautifulsoup」の使い方については以下の記事がわかりやすいです。

次に、requestsもインストールします。

!pip install requests

例えば「requests」の使い方については以下の記事がわかりやすいです。

​Google Collaboratoryでは以下のようになります(既にインストール済みなのでalready satisfiedと出ています。)

画像1

これで「Beautiful Soup」と「requests」が使えるようになりました。

☟ここからがPythonのコードを書いていくところです。

Google Collaboratoryを使っているので、以下コードを書いて実行しながら進めていきます。

必要なライブラリをインポートする

「Beautiful Soup」と「requests」を使うために、以下のようにしてライブラリをインポートします。

import requests
from bs4 import BeautifulSoup

先ほど上手くインストールができていればここでは特にエラーなく進むはずです。

アマゾンのサイトにいって「Pythonスクレイピング」の検索に引っかかった書籍のタイトルを抽出する

アマゾンのサイトにいって「Pythonスクレイピング」と検索します。

そのときのURLがこちらです。

https://www.amazon.co.jp/s?k=Pythonスクレイピング&__mk_ja_JP=カタカナ&ref=nb_sb_noss_2

画像2

なので、以下のように

●URLを指定
●requests.get()は名前の通りHTTPのGETメソッドに相当

keyword = 'Pythonスクレイピング'

url = "https://www.amazon.co.jp/s?k=" + keyword + "&__mk_ja_JP=カタカナ&ref=nb_sb_noss_2"

response = requests.get(url)
print(response)

【結果】
<Response [200]>

このようにresponseオブジェクトとして返ってきます。

responseの属性を使って文字列を出力してみます。
それには、次のようにtext属性を使います。

print(response.text)

すると以下のようにアマゾンサイトのHTMLが出力されます。

画像3

この中から「書籍のタイトル」と「値段」を抽出していけば良いです。

上記のままだと見にくいので、「HTMLパーサー」を使って文字列を見やすくします。

html =response.text

#htmlパーサー
soup = BeautifulSoup(html,'html.parser')

print(soup.text)

ちょっと見た目が変わった(?)気がしますね。

画像4

あとは、ここからHTML構文から必要な記述があるCSSのクラスを絞り込んでいきます。

画像5

まず、「.sg-col-inner」がひとつの本に対する大枠です。

画像6

だから、まず「.sg-col-inner」を抽出します。

items = soup.select('.sg-col-inner')
print(items)
print(type(items))

itemsはリスト型になっているので、「items.text」とするとエラーが出るので注意してください。
「.text」は一つの要素にしか使うことができません。

だから、for文を使ってリストのひとつひとつの要素を抽出しながら「.text」とすれば良いです。

for item in items:
 print(item.text)

☟こんな感じでエラーなく表示できます。

画像7

さらにここからタイトルだけを絞り込みたいとして。。。。HTML構文を調べに行きます。

タイトルに充てられているCSSのクラスは「a-size-base-plus」と分かったので、for文でitemsのリストをひとつひとつ要素を抽出(書籍ごとに抽出)して、「.select_one」を使ってタイトルのCSSクラスの値をtitleに入れています。

そして、title_lsitとして空のリストファイルに値を入れていってきます。

title_list = []
#.text.replace('\n', '')
for item in items:
 title = item.select_one('.a-size-base-plus')
 title_list.append(title)

title_list

結果を見てみると、以下のようになっています。

画像8

はじめに「None」がいくつか見えますよね。
これは、タイトル以外にも「.sg-col-inner」が使われているため「.sg-col-inner」の中の「.a-size-base-plus」には値がないために出てしまった空の値です。
※本当はもっと良いCSSクラスの絞り方をした方が良いかもしれませんが、今回はあまり良さげなCSSクラスはなかったのでこのままいきます。

Noneが邪魔なので以下のfilter関数でNoneを消します。

title_list_  = filter(None,title_list)
print(title_list_)
print(type(title_list_))

print文の結果を見ると、
<filter object at 0x7fd821cc9b38>
<class 'filter'>
となっています。

filterオブジェクトとして値を返しているようです。

リストの値を出すためには、

list(title_list_)

とすれば良いです。

これを別名で保存しておきます。

title_lists = list(title_list_)

では、最後に「title_lists」をfor文で回してひとつひとつの要素を取り出して、「title_name」にappendで追加していきましょう。

title_name = []
for title in title_lists:
 title_name.append(title.text)

title_name

画像9

はい、これでタイトルだけリストにすることができました(^^♪


全体のコード

全体のコードを載せておいた方がわかりやすいでしょう(^^)/

import requests
from bs4 import BeautifulSoup

keyword = 'Pythonスクレイピング'

# url = "https://www.amazon.co.jp/s?k=" + keyword + "&__mk_ja_JP=カタカナ&ref=nb_sb_noss_2"
url = "https://www.amazon.co.jp/s?k=" + keyword + "&__mk_ja_JP=カタカナ&ref=nb_sb_noss_2"

response = requests.get(url)
html =response.text

#htmlパーサー
soup = BeautifulSoup(html,'html.parser')

items = soup.select('.sg-col-inner')

title_list = []

#タイトルの抽出
for item in items:
 title = item.select_one('.a-size-base-plus')
 title_list.append(title)

#Noneの削除
title_list_  = filter(None,title_list)
title_lists = list(title_list_)


title_name = []
for title in title_lists:
 title_name.append(title.text)

title_name

これで実行すると、以下のようになります。

画像10

今日は以上です。

僕は☟こちらの参考書でも勉強しはじめています('ω')ノ

Twitter➡@t_kun_kamakiri
ブログ➡宇宙に入ったカマキリ(物理ブログ)

この記事が気に入ったらサポートをしてみませんか?