ECサイトにログインして連続して複数ページの情報を取得する|Python

ECsite-WEBscrapingpython

ECサイトにログインして連続して複数の商品ページの情報をPythonで取得する方法を紹介します。
手動で1件1件情報を確認するとなるととても時間の掛かる作業ですが、Pythonでプログラムを組んでしまえば、自動的に情報取得してくれます。

ライブラリやパッケージのインポート

#ライブラリやパッケージのインポート
import csv
import numpy as np
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary

import csv

CSVファイルを入出力するためのモジュールをインポートします。

Pythonの標準モジュールのためインストールすることなく利用できます。

import numpy as np

Pythonの拡張モジュール「NumPy」をインポートします。
NumPyはリストを使って大量のデータ処理にかかる時間を短縮できます。
機械学習や画像処理など、大量のデータ処理を行う際に使用されます。

インストールされていない場合は下記をコマンドラインで実行します。

pip install numpy

from selenium import webdriver

Pythonでブラウザ操作を行うためにseleniumのwebdriverをインポートします。

インストールされていない場合は下記をコマンドラインで実行します。

pip install selenium

from selenium.webdriver.chrome.options import Options

seleniumを動作させる設定を行うためOptionsクラスをインポートします。

import chromedriver_binary

chromeブラウザを動作させるためにchromedriver_binaryをインポートします。
chromedriver_binaryはPATHを通す必要が無いため便利です。

インストールされていない場合は下記をコマンドラインで実行します。

pip install chromedriver_binary=={chromedriverのバージョン}

{chromeドライバーのバージョン}の箇所にインストールするchromedriverのバージョンを指定します。

インストールするバージョンの指定はこちらを参考にしてください。
chromedriverバージョン違いで動作しないときの対処法|selenium

商品ページURLの読み込み

#==商品ページURLを読み込む
with open({itemURL_file}, mode=’r’, encoding=’UTF-8′) as f:
itmURLs = f.readlines()

商品ページの一覧を記載した{itemURL_file}を読み込みます。
読み取りモードであるmode='r'の指定と、エンコードのencoding='UTF-8'を指定しています。

商品ページURLはreadlines()を使って改行コードごとに分割したリストとして取得します。
取得した結果には改行コード\nが含まれます。

{itemURL_file}には下記の形式で1行に1商品ページのURLを記載し保存しておきます。

https://xxxxxxx/0000001
https://xxxxxxx/0000002
https://xxxxxxx/0000003
https://xxxxxxx/0000004
https://xxxxxxx/0000005

取得結果の出力ファイルの準備

#=出力ファイルに項目名を追記する
names = ‘商品名’ + ‘,’ + ‘商品コード’ + ‘,’ + ‘説明’ + ‘,’ + ‘商品価格’ + ‘,’ + ‘カテゴリー’ + ‘\n’
with open({itemInfo_file}, mode=’w’, encoding=’UTF-8′) as f:
f.write(names)

変数namesに取得する項目名をセットします。

取得した商品ページの情報を書き込むファイルを{itemInfo_file}で指定します。
書き込みモードであるmode='w'の指定と、エンコードのencoding='UTF-8'を指定しています。

変数namesにセットされている項目名をファイルに書き出します。

selenium動作設定

#=selenium動作設定
options = Options()
options.add_argument(‘–headless’)
options.add_argument(‘–disable-gpu’)
options.add_argument(‘–disable-dev-shm-usage’)
options.add_argument(‘–no-sandbox’)
driver = webdriver.Chrome(‘chromedriver’, options=options)

selenumをヘッドレスモードで動作させます。

ECサイトへのログイン

#=ログイン処理
#==ブラウザを起動しECサイトを開く
driver.get({site_url})
#==IDを入力する
element = driver.find_element_by_xpath({login_ID})
element.send_keys({loginID})
#==PASSWORDを入力する
element = driver.find_element_by_xpath({login_PASSWORD})
element.send_keys(loginPASS)
#==ログインボタンをクリックする
element = driver.find_element_by_xpath({login_BUTTON})
element.click()

{site_url}にECサイトログイン画面のURLを記載します。

element = driver.find_element_by_xpathで指定する{login_ID}にログインIDを入力する箇所のxpathを記載します。
element.send_keysでログインID{loginID}を入力します。

次のelement = driver.find_element_by_xpathで指定する{login_PASSWORD}にログインパスワードを入力する箇所のxpathを記載します。
element.send_keysでログインID{loginPASS}を入力します。

そして3つ目のelement = driver.find_element_by_xpathで指定する{login_BUTTON}に記載する場所のログインボタンを、element.click()でクリックしログインします。

商品ページを開く

#=for構文でリストitemURLsからitemURLに一つずつ値を取り出す
for itemURL in itmURLs:
#==商品ページを開く
driver.get(itemURL)

商品ページの各要素を取得する

商品名の取得

#==商品名
element = ”
itmName = ”
element = driver.find_element_by_xpath({itemNAME})
itmName = element.text

商品コードの取得

#==商品コードブロックの要素取得
element = ”
itmCode = ”
element = driver.find_element_by_xpath({item_CODE})
itmCodeBlock = element.text

#===JANコードの抽出
index1 = janCodeBlock.find(‘\n’)
itmCode = janCodeBlock[0:index1]

#====不要な文字列を変換
itmCode = janCode.replace(‘商品コード:’,”)

商品コードを取得します。

しかし、商品コードは一つのブロックに他の情報合わせて2行で記載されていました。

商品コード:1234567890
カタログ : 409
0

そのため、商品コードのみを抽出するために文字列操作を行います。

まずindex1 = itmCodeBlock.find('\n')で改行までの文字数を取得します。
そしてitmCode = janCodeBlock[0:index1]で文字の先頭から改行の手前までを取りだし、変数itemCodeにセットします。

次にitmCode = janCode.replace('商品コード:','')で文字列先頭の項目名「商品コード:」を除去します。

商品の説明の取得

#==商品の説明
element = ”
spec = ”
element = driver.find_element_by_xpath({item_DETAIL})
spec = element.text

#===不要な文字列を変換
spec = spec.replace(‘\n’,’●’)
spec = spec.replace(‘●●’,’●’)

商品の説明は表組みされており取得すると複数行となるため、1行に変換します。
その際に改行は区切りが分かる様に「●」に変換しています。
なお変換の結果「●●」となってしまう箇所があることから「●●」は「●」に再度変換します。

商品価格の取得

#==商品価格
element = ”
itmPrice = ”
element = driver.find_element_by_xpath({item_PRICE})
itmPrice = element.text

#====不要な文字列を変換
itmPrice = itmPrice.replace(‘円’,””)
itmPrice = itmPrice.replace(‘,’,””)

カテゴリーの取得

#==カテゴリー
element = ”
Cate = ”
element = driver.find_element_by_xpath({item_CATEGORY})
Cate = element.text

取得した商品情報を連結する

#=取得した商品情報を連結する
itminfo = itmName + ‘,’ + itmCode + ‘,’ + spec + ‘,’ + itmPrice + ‘,’ + Cate + ‘\n’

取得した商品情報をカンマ区切りで連結、末尾に改行を付加し、変数itminfoにセットします。

取得した商品情報をファイルに書き出す

#=取得した商品情報を都度書き出す
with open({itemInfo_file}, mode=’a’, encoding=’UTF-8′) as f:
f.write(itminfo)

商品情報を1商品分を取得する都度、ファイルに書き出します。

ファイルは追記書き込みモードmode='a'で開きます。

そうすることで大量の商品情報を取得する際に、もし途中で処理が止まってしまってもその直前までの取得情報は保存されており最初からやり直す必要が無くなります。

ここまでがfor構文の繰り返し処理です。

ブラウザを閉じる

#ブラウザを閉じる
driver.close()

最後にブラウザを閉じます。

今回説明したコード全体

#ライブラリやパッケージのインポート
import csv
import numpy as np
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary

#==商品ページURLを読み込む
with open({itemURL_file}, mode=’r’, encoding=’UTF-8′) as f:
itmURLs = f.readlines()

names = ‘商品名’ + ‘,’ + ‘商品コード’ + ‘,’ + ‘説明’ + ‘,’ + ‘商品価格’ + ‘,’ + ‘カテゴリー’ + ‘\n’
with open({itemInfo_file}, mode=’w’, encoding=’UTF-8′) as f:
f.write(names)

#=selenium動作設定
options = Options()
options.add_argument(‘–headless’)
options.add_argument(‘–disable-gpu’)
options.add_argument(‘–disable-dev-shm-usage’)
options.add_argument(‘–no-sandbox’)
driver = webdriver.Chrome(‘chromedriver’, options=options)

#=ログイン処理
#==ブラウザを起動しECサイトを開く
driver.get({site_url})
#==IDを入力する
element = driver.find_element_by_xpath({login_ID})
element.send_keys({loginID})
#==PASSWORDを入力する
element = driver.find_element_by_xpath({login_PASSWORD})
element.send_keys(loginPASS)
#==ログインボタンをクリックする
element = driver.find_element_by_xpath({login_BUTTON})
element.click()

#=for構文でリストitemURLsからitemURLに一つずつ値を取り出す
for itemURL in itmURLs:
#==商品ページを開く
driver.get(itemURL)

#==商品名
element = ”
itmName = ”
element = driver.find_element_by_xpath({itemNAME})
itmName = element.text

#==商品コードブロックの要素取得
element = ”
itmCode = ”
element = driver.find_element_by_xpath({item_CODE})
itmCodeBlock = element.text

#===JANコードの抽出
index1 = janCodeBlock.find(‘\n’)
itmCode = janCodeBlock[0:index1]

#====不要な文字列を変換
itmCode = janCode.replace(‘商品コード:’,”)

#==商品の説明
element = ”
spec = ”
element = driver.find_element_by_xpath({item_DETAIL})
spec = element.text

#===不要な文字列を変換
spec = spec.replace(‘\n’,’●’)
spec = spec.replace(‘●●’,’●’)

#==商品価格
element = ”
itmPrice = ”
element = driver.find_element_by_xpath({item_PRICE})
itmPrice = element.text

#====不要な文字列を変換
itmPrice = itmPrice.replace(‘円’,””)
itmPrice = itmPrice.replace(‘,’,””)

#==カテゴリー
element = ”
Cate = ”
element = driver.find_element_by_xpath({item_CATEGORY})
Cate = element.text

#=取得した商品情報を連結する
itminfo = itmName + ‘,’ + itmCode + ‘,’ + spec + ‘,’ + itmPrice + ‘,’ + Cate + ‘\n’

#=取得した商品情報を都度書き出す
with open({itemInfo_file}, mode=’a’, encoding=’UTF-8′) as f:
f.write(itminfo)

#ブラウザを閉じる
driver.close()

コメント