0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでSeleniumとopenpyxlを使い、EXCELの商品リストから自動でカートに入れる

Last updated at Posted at 2020-05-01

概要

大学のロボット部で部品を買うのですが、管理をしやすくするために個人でバラバラに買わずに購入品目をEXCELでまとめて購入担当にリストを渡すことで購入してもらっています。購入品をまとめる作業もリストからURLを一つ一つ通販サイトにコピーしてカートに入れるのも数が多くて面倒くさい!ということで、今回は既に作ってある商品リストのEXCELファイルを読み込ませて自動でカート追加まで行うプログラムを作成してみました。
簡単に書けそうだったので言語はpythonにしました。

環境

ASUS zenbook UX310U
Windows10 home (64bit)
CPU Intel core i5 7200U
Google Chrme 81.0.4044.92
ChromeDriver 81.0.4044.69
Python 3.7.3(Anaconda)
エディタ Sublime Text3
selenium
openpyxl

環境構築手順

Python 環境は Anaconda3です。Anaconadaをインストールしていない人はインストールしましょう。

必要パッケージのインストール

こちらを参考に必要パッケージおよびドライバーをインストールしました。

seleniumインストール

まずはanaconda promptを起動して新しく仮想環境を作ります。既にインストール済みのパッケージの依存関係によってはエラーが出ることがあるので新しい仮想環境にインストールすることを勧めます。

conda create -n selenium

仮想環境の切り替え

conda activate selenium

インストール

conda install selenium

ChromeDriver のインストール

今回はpipでインストールし、パス通さないでスクリプト内でインポートします。
https://qiita.com/hanzawak/items/2ab4d2a333d6be6ac760
を参考にしてインストールを進めていけばできます。
以下に一応やった手順を示します。
google chromeのバージョンを確認すると81.0.4044.92だったのでChromeDriverのダウンロードページで自分のchromeバージョンに近い番号を探してインストールします。(バージョンが下で近いものがいいかもしれません)

pip install chromedriver-binary==81.0.4044.69

ちなみに今回はpipでインストールしましたが、こちらのサイトにバイナリでダウンロードする方法も書いてあります。

openpyxlのインストール

pythonでEXCELファイルを読み書きするパッケージです。詳しい使い方はこの方の記事が参考になると思います。
以下のコマンドでインストールします。

conda install openpyxl

ExcelファイルにあるURLの取得

ひとまずExcelファイル内にある全てのURLと購入個数と購入場所の取得までやってみます。予めURLと購入個数のセルは決まっているので指定してリストにしています。何も書かれていないセルでエラーが出るのを防ぐためにfor文で取得しています。

buy_excel.PNG
今回は自作した写真にあるようなリストを使います。

add_cart.py

import sys
from argparse import ArgumentParser as Parser
import openpyxl

parser = Parser(description='EXCELに書かれた商品リストを自動的にカートに入れるスクリプト')
parser.add_argument("path",type=str,help='excelファイルのパスを指定')
args = parser.parse_args()
wb = openpyxl.load_workbook(args.path)
sheet = wb['Sheet1']
url=[]
buy_quan=[]
site=[]
for sell in sheet.iter_rows(min_row=2,max_col=8):
	values = []
	for col in sell:
		values.append(col.value)
	if values[7] != None:
		url.append(values[7])
	if values[6] != None:
		buy_quan.append(values[6])
	if values[3] != None:
		site.append(values[3])


print(url)
print(buy_quan)
print(state)

実行するときは以下のコマンドです。引数にはExcelのファイルパスを指定します。実行してURL、購入個数、購入場所の順番でリストが表示されれば成功です。

python listup_from_excel.py filepass

URL表示からカート追加まで

先程のプログラムの続きです。
今回は秋月電子の通販サイトでやってみます。まず、適当な商品ページで購入数量のテキストボックスを右クリックし、「検証」をクリックしてHTMLの要素を表示します。ハイライトされている部分で右クリックし、Xpathをコピーします。
詳しい方法は以下で解説されています。
https://youtu.be/AyicRGWa_70

driver.find_element_by_xpath('xpass')
の引数にコピーしたXpathを貼り付けます。ちなみにXpathはシングルクォーテーションで囲みます。ダブルクオーテーションはだめです。

add_cart.py
from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()#chromeを開く
driver.get('http://akizukidenshi.com/catalog/g/gM-06187/')
wait=WebDriverWait(driver, 10)
# 購入数量のxpathを指定する
element = driver.find_element_by_xpath('//*[@id="maincontents"]/div[2]/table/tbody/tr/td[3]/input')
element.clear()
element.send_keys("6")
element.send_keys(Keys.RETURN)

最後のelement.send_keys(Keys.RETURN)は購入数量を入力した状態でEnterキーを押すとそのままカートに入るので横着しています。しかし、このままだと在庫切れでテキストボックスが表示されなかったときにカートに入れられません。

全体のコード

使い回せるようにクラスにまとめました。正常にカートに追加できなかったときのために例外処理を入れています。

add_from_excel.py
from argparse import ArgumentParser as Parser
import openpyxl

from selenium import webdriver
import chromedriver_binary
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
url = []#URL
buy_quan = []#購入数量
site = []#購入サイト名
prduct_name = []#製品名
driver = webdriver.Chrome()# chromeを開く

def ListXlsElemet(url_row, buy_quan_row, site_row, proname_row): 
    parser = Parser(description='EXCELに書かれた商品リストを自動的にカートに入れるスクリプト')
    parser.add_argument("path", type=str, help='excelファイルのパスを指定')
    args = parser.parse_args()
    wb = openpyxl.load_workbook(args.path)
    sheet = wb['Sheet1']
    for sell in sheet.iter_rows(min_row=2, max_col=8):
        values = []
        for col in sell:
            values.append(col.value)
        if values[url_row] != None:
            url.append(values[url_row])
        if values[buy_quan_row] != None:
            buy_quan.append(values[buy_quan_row])
        if values[site_row] != None:
            site.append(values[site_row])
        prduct_name.append(values[proname_row])


class GoToCart:
    def __init__(self, arg_url, arg_quan, arg_site,arg_proname):
   
        self.url = arg_url
        self.buy_quan = arg_quan
        self.site = arg_site
        self.proname=arg_proname
    def CharClassifi(self, ch, target):  # 特定の文字列を含むかどうかを判定し、一致したらリストに追加する関数
        relist = []
        num = 0
        for char in self.site:
            if str(char) == ch:
                relist.append(target[num])

            num = num + 1
        return relist

    # サイト名とxpthsを渡すと必要数分カートに入れる関数
    def AddCart(self, site_name, num_xpath, cart_xpath):
        temp_url = self.CharClassifi(site_name, self.url)
        temp_quan = self.CharClassifi(site_name, self.buy_quan)
        temp_proname = self.CharClassifi(site_name, self.proname)
        num = 0
        helth=0
        for t_url in temp_url:
            try:
                driver.get(t_url)
                wait = WebDriverWait(driver, 10)
                # 購入数量のxpathを指定する
                t_element = driver.find_element_by_xpath(num_xpath)
                t_element.clear()
                t_element.send_keys(str(temp_quan[num]))
                c_element = driver.find_element_by_xpath(cart_xpath)#カートボタンのxpath
                c_element.click()
                
                
            except:
                    print(temp_proname[num])
                    print("カートに入れられません。商品が存在しないか在庫がない可能性があります")
                    continue
            num = num+1

class ChildGotoCart(GoToCart):
    def Akiduki(self):
        self.AddCart( "秋月", '//*[@id="maincontents"]/div[2]/table/tbody/tr/td[3]/input','//*[@id="maincontents"]/div[2]/table/tbody/tr/td[4]/input')

    def Sengoku(self):
        driver.execute_script("window.open()")#新規ウィンドウオープン
        driver.switch_to.window(driver.window_handles[1])#新規タブに切り替え
        self.AddCart("千石",'//*[@id="detail_price"]/tbody/tr/td[2]/input','//*[@id="detail_price"]/tbody/tr/td[3]/input')
    
def main():
    buy_handle = ChildGotoCart(url, buy_quan, site,prduct_name)
    ListXlsElemet(7, 6, 3,2)
    buy_handle.Akiduki()
    buy_handle.Sengoku()
    print("完了しました")
    return 0


if __name__ == "__main__":
    main()

関数の使い方

ListXlsElemet(URL,購入数量,購入サイト名,製品名) 各対応するExcelの列番号が入ります。一番左列から0です。
AddCart(Excelに書いてあるサイト名,購入数量のXpath,カートボタンのXpath)
他のサイトを追加したい場合はChildGotoCartクラスに追加してmain()から呼び出すだけです。

実行するにはanadonda promptで引数にexcelのファイルパスを指定して実行します。

(selenium)C:\Users\username>python buy_from_excel.py filefass

その他参考

seleniumクイックリファレンス
seleniumでリンクを別タブで開く

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?