Pythonのrequests,bs4をつかったスクレイピング ケーズ電気の検索結果をCSV出力

python Scraping
この記事は約12分で読めます。

スクレイピングする題材

今回のスクレイピングでは
検索結果をデータ化しようと思います。

ここからの内容についてはpythonのプログラムを
jupyter notebook
で記述していきます。
インストールなどまだな方は予めインストールが必要です。
"jupyter notebook" "インストール"などで
ググっていただくといいかと思います。

スクレイピング可能かどうか調べる

今回は家電量販店として有名な
ケーズ電気さんのwebサイトでスクレイピングさせていただこうと思います。

以前の

同様スクレイピング可能か調べます。

ケーズ電気の利用規約へ

Windowsの方なら Ctrl + F 、
Macの方なら command + F
でページ内の文言を検索することができますので、
[ロボット、自動、スクレイピング、クローリング]
などの単語で検索結果が出てこなければ概ね大丈夫です。
とはいえ、相手方サーバーに負荷のかかりにくいプログラムを
作る必要はあります。

URLへの検索文字の挿入

通常のスクレイピングの場合、
定まったURLを変数に入れてスクレイピングするのですが、
今回は検索文字を入力して結果をデータ化します。
通常検索窓に検索文字をいれて検索するとURLは下記のようになります。
今回は 扇風機 と入力してみました。

https://www.ksdenki.com/shop/goods/search.aspx?search=x&keyword=%90%EE%95%97%8B%40

おそらく keyword= のあとが検索文字だと思われます。
ここらか、このような結果にするにはどうしたものかと
いろいろ調べました(笑)

で、結局どういう原理か細かい部分までは理解していませんが、
下記コードで文字の変換が可能であることがわかりました。

import chardet
import urllib.parse

post_data = {'KEY1':key_word}
urlencode_post_data = urllib.parse.urlencode(post_data, encoding='')

これで変換できることはわかったのですが、
encoding='' の部分に今回のケーズデンキのサイトにあう文字コード
を入れなければいけません。
プログラムに詳しい人だとスマートに見つけることができるんだと思うのですが
私の場合はひたすらいろんな文字コードを入れてみました(笑)
その結果、今回は encoding='Shift-JIS'  でいけました。

#検索キーワードを入力
key_word = '扇風機'

# shift-jisでエンコードし、str型にする
post_data = {'KEY1':key_word}
urlencode_post_data = urllib.parse.urlencode(post_data, encoding='Shift-JIS')

で、今回の変換プログラムですが、
KEY1= の形で出力されますので、検索urlに入れるときは
KEY1= を取り除く必要があります。

#変換された検索文字をフォーマット文の型でいれます{}
url = 'https://www.ksdenki.com/shop/goods/search.aspx?p=1&search=x&keyword={}'

#フォーマト文の形で検索文字をいれて変数target_urlにいれます。
target_url = url.format(urlencode_post_data)

#不要なKEY1=を取り除きます。
get_url = target_url.replace('KEY1=','')

その結果、検索窓に 扇風機 をいれたURLが下記となります。

get_url
'https://www.ksdenki.com/shop/goods/search.aspx?p=1&search=x&keyword=%90%EE%95%97%8B%40'

というわけで、やっとURLをゲットです。
ここからは通常のスクレイピングと同様になります。

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

スクレイピングに必要なライブラリをimport します。
サーバーにリクエストを送ってhtmlデータを取得する
requests 

取得したhtmlデータから div タグの class名 xxxx を取得
できるようにしてくれる
BeautifulSoup

最後に取得したデータをデータフレームに入れて
csv出力しますので、
pandas 

さらに今回は文字変換に必要なライブラリも import します。

#ライブラリのインポート
from bs4 import BeautifulSoup
import requests
from time import sleep
import pandas as pd
import chardet
import urllib.parse

そして冒頭で作成した、検索文字からurlを作成するプログラム。

#検索キーワードを入力
key_word = '扇風機'

#変換した文字列にはKEY1=が付いているので削除してformat文でurlに付け加える
url = 'https://www.ksdenki.com/shop/goods/search.aspx?p=1&search=x&keyword={}'
target_url = url.format(urlencode_post_data)
get_url = target_url.replace('KEY1=','')

検索結果の全体を取得します。

このURLからソースコードを取得して
ソースコードから情報を取得できるように
BeautifulSoupでインスタンスを作成します。

#htmlデータを抽出してBeautifulSoupで解析
r = requests.get(get_url)
soup = BeautifulSoup(r.text)

ここまでくると、Google Chromeの出番です。
chromで対象のホームページを開き、
ページ上で右クリック。
すると”検証”という項目が出てきますので、クリックすると
html と webページが二画面で表示されます。

検証ツールのポインターをクリックして
webページ上を動かしていくと対象個所の色が反転して、
そこを構成するhtmlが表示されます。

ここからページ上をドラックしていって
検索結果の商品の塊の部分が反転した所でクリック。
今回のお目当ての部分は
ul の  class_='goods_list_items_ul_ に商品群が入っていました。
各商品は li の中に入っています。

#商品データ群の入った塊を 変数item_allに代入
item_all = soup.find('ul', class_='goods_list_items_ul_')

#そこからfind_allで検索結果の全ての商品をリスト形式で
#変数contents に代入
contents = item_all.find_all('li')

全体から一件のデータを取得必要なデータを取得

全体の検索結果のデータから一件のデータを抽出します。
contents にリスト形式で全体が入っているので
contents[0]で初めの一件を取得することができます。


この一件から、商品名 価格 アウトレツト、特別価格などの項目
取得しようと思います。

#contents[0]をcotentに代入
content = contents[0]

商品名は結構わかりやすくて

item_name = content.find('a').get('title')
item_name

'ユアサプライムス\xa0ケーズデンキオリジナル扇風機(リモコン)\xa0KS-F33MR-W'

改行を現す文字が化けているのか、\xa0という文字列が改行
されているであろう場所に入っているので、これをreplaceで削除します。

item_name = content.find('a').get('title').replace('\xa0','')

商品価格は
span の  class_='carousel_list_price_' に入っていますので
.textで抽出します。

item_price = content.find('span',class_='carousel_list_price_').text

出力結果は'6,578円'と文字列です。
必要であれば, と円 を削除して int型に変換することも
かのうですが、今回はこのままにします。

#int型に変換した場合
int(item_price.replace('円','').replace(',',''))
6578

最後は店頭受取可、あんしんパスポート会員特典など
サービス面の情報の取得です。
情報は divタグの class_='goodsspec_icon_'
の中にはいっています。
それを変数specに代入します。

spec = content.find('div',class_='goodsspec_icon_')

spec
<div class="goodsspec_icon_">
<img alt="その場で使えるクーポン対象商品" height="19px" src="//image.ksdenki.com/img/sys/icn_product_coupon.png" width="171px"/>
<img alt="店頭受取可" height="19px" src="//image.ksdenki.com/img/sys/icn_product_tentou.png" width="84px"/>
<img alt="あんしんパスポート会員特典" height="19px" src="//image.ksdenki.com/img/sys/icn_product_anshinpass.png" width="171px"/>
</div>

そこからfind_allimgタグの情報をリスト形式で
変数iconsに代入します。

icons = spec.find_all('img')

icons
[<img alt="その場で使えるクーポン対象商品" height="19px" src="//image.ksdenki.com/img/sys/icn_product_coupon.png" width="171px"/>,
 <img alt="店頭受取可" height="19px" src="//image.ksdenki.com/img/sys/icn_product_tentou.png" width="84px"/>,
 <img alt="あんしんパスポート会員特典" height="19px" src="//image.ksdenki.com/img/sys/icn_product_anshinpass.png" width="171px"/>]

商品によってサービスの数はことなってきますので、
空のリスト
s = []
を初めに定義してappendで追加していきます。
icon.get('alt')
でサービス内容をテキストで抽出できます。

s = []
icons = spec.find_all('img')
for icon in icons:
a = icon.get('alt')
s.append(a)

s
['その場で使えるクーポン対象商品', '店頭受取可', 'あんしんパスポート会員特典']

for文で全てのデータを取得

これで目的の商品名 価格 アウトレツト、特別価格
を取得することができたので取得したデータを
一件づつ辞書型で取得し、それらをリスト型データに追加していきます。

#取得したデータを全件を格納するリストを作成
d_list = []

for content in contents:
        item_name = content.find('a').get('title').replace('\xa0','')
        item_price = content.find('span',class_='carousel_list_price_').text
        spec = content.find('div',class_='goodsspec_icon_')
        s = []
        icons = spec.find_all('img')
        for icon in icons:
            a = icon.get('alt')
            s.append(a)

#取得したデータを辞書型で格納
        d = {
             'name' : item_name,
             'price': item_price,
             'serve': '・'.join(s)


        }
#取得したデータを辞書型データをd_list に追加していきます。
        d_list.append(d)

最後は取得した  d_list データをpandasのデータフレームに格納して
csv出力します。 文字化け防止でエンコードします。
encoding='utf_8_sig'
今回はindexを出力しない形式でcsvを出力します。

df = pd.DataFrame(d_list)
df.to_csv('test.csv' ,encoding='utf_8_sig' ,index = False )

以上でケーズデンキさんの検索結果をデータ化することに成功しました。

Python スクレイピング関連記事

コメント

タイトルとURLをコピーしました