スクレイピングする題材
今回のスクレイピングでは
検索結果をデータ化しようと思います。
ここからの内容については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_allでimgタグの情報をリスト形式で
変数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 スクレイピング関連記事
コメント