たいへん困っています、、
実現したいこと
Keezonからスプシへのスクレイピングが絶対にずれないようにしたいです。
前提
当方、コード初心者です。
Pythonでスクレイピングコードを組み、Keezonというアマゾンの商品販売価格等を抽出して、スプレッドシートへ転記するコードが実装されています。手順としては、スプシのASIN(アマゾン上の一意なJANコードのようなもの)を参照し、そのASINをKeezonサイトの検索バーで検索。その商品のライバル出品者数や中古最安値等を抽出、スプシに転記していく流れです。
発生している問題・エラーメッセージ
問題なくスプシの商品リストは400件以上あり、大体200件目を越えたあたりから、ASINがズレて参照されます。
具体的には、1、2行前のASINのKeezon情報を抽出してしまうなど。
ただ、一度ずれても途中で正しくスクレイピングがされる場合もあります。
Anacondapromptで直接実行していますが、特にエラー文は吐き出しません。
バッチファイルでの実行も同様です。
該当のソースコード
python
1from google.oauth2.service_account import Credentials 2import gspread 3from selenium import webdriver 4from webdriver_manager.chrome import ChromeDriverManager 5from selenium.webdriver.common.by import By 6from selenium.webdriver.chrome.service import Service as ChromeService 7import os 8import time 9from bs4 import BeautifulSoup 10import pandas as pd 11from datetime import datetime 12import re 13import numpy as np 14 15 16 17 18 19 20 21scopes = [22 'https://www.googleapis.com/auth/spreadsheets',23 'https://www.googleapis.com/auth/drive'24]25 26credentials = Credentials.from_service_account_file(27 './gspread-used-list-auto-update-30cf7eed69e4.json',28 scopes=scopes 29)30 31gc = gspread.authorize(credentials)32 33spreadsheet_url = 'https://docs.google.com/spreadsheets/d/1GQBTvllqXLp5VC1Dmgh2L2ya2LfAxaBg7R8lwld2bMU'34spreadsheet = gc.open_by_url(spreadsheet_url)35 36 37data = spreadsheet.sheet1.get_all_values()38 39df_sheet = pd.DataFrame(data)40 41#それぞれの項目の位置を確認42title = df_sheet.loc[1].to_list()43index_update = title.index('更新有無')44index_rotate = title.index('回転数')45index_rival = title.index('ライバル')46index_new= title.index('新品\n最安値')47index_old = title.index('中古\n最安値')48index_sell = title.index('販売\n予定金額')49index_date = title.index('更新日')50index_asin = title.index('ASIN')51# index_watch = title.index('フリマウォッチ\n変更済')52 53 54#スクレイピング55 56options = webdriver.ChromeOptions()57# options.add_argument('--headless') #実行時にブラウザを表示しない58 59 60driver = webdriver.Chrome()61 62 63driver.get('https://keezon.net/user/index')64 65mail = 'メールアドレス'66passwd = 'パスワード'67 68#ログイン69driver.find_element(By.NAME, 'email').send_keys(mail)70driver.find_element(By.NAME, 'password').send_keys(passwd)71driver.find_element(By.NAME, 'submit').click()72 73driver.implicitly_wait(10)74 75for i in range(2,len(df_sheet)):76 77 ASIN = df_sheet[index_asin][i]78 UPDATE = df_sheet[index_update][i]79 OLD_SELL = df_sheet[index_sell][i]80 81 # スプレッドシートのASINになにも書かれていない列にきたらブレイクしてループを終わらせる82 if ASIN == '':83 break84 85 # 更新有無がTRUEだったら以下の処理を行う86 if UPDATE == 'TRUE':87 88 # ループの始め以外は検索欄に前のASINが記入されているので、それを一旦消す89 if i != 2:90 driver.find_element(By.NAME, 'ASIN').clear()91 92 driver.find_element(By.NAME, 'ASIN').send_keys(ASIN)93 driver.find_element(By.ID, 'itemsearch').click()94 95 driver.implicitly_wait(10)96 97 # 1秒間プログラムを一時停止する98 time.sleep(1)99 100 101 # ページ上のtableを全て取得102 df = pd.read_html(driver.page_source)103 rotate_num = df[0]['平均'][2] #回転数104 rival = df[2]['[中]数'][0] #ライバル105 106 if pd.isnull(rival):107 rival = '0'108 109 for ii in range(len(df)):110 new_num = df[2]['[新]値'][ii] #新品最安値111 if pd.isnull(new_num) == False:112 break113 114 for iii in range(len(df)):115 old_num = df[2]['[中]値'][iii] #中古最安値116 if pd.isnull(old_num) == False:117 break118 119 120 121 #販売予定金額122 for j in range(len(df[2])-1):123 if df[2]['[中]数'][j] < df[2]['[中]数'][j+1] and df[2]['順位'][j] < df[2]['順位'][j+1]:124 # print(df[2]['調査日'][i])125 sell_num = df[2]['[中]値'][j+1]126 break127 128 # 最後まで判定したが、該当するものがなかった場合129 if i == len(df[2]) - 2:130 sell_num = OLD_SELL 131 132 133 #スプレッドシートへ書き込み134 spreadsheet.sheet1.update_cell(i+1, index_rotate+1, str(rotate_num))135 spreadsheet.sheet1.update_cell(i+1, index_rival+1, str(rival))136 spreadsheet.sheet1.update_cell(i+1, index_new+1, str(new_num))137 spreadsheet.sheet1.update_cell(i+1, index_old+1, str(old_num))138 spreadsheet.sheet1.update_cell(i+1, index_date+1, str(datetime.today().strftime('%Y/%m/%d')))139 140 print('ASIN ', ASIN)141 print('回転数 ',rotate_num)142 print('ライバル ', rival)143 print('新品最安値 ', new_num)144 print('中古最安値 ', old_num)145 146 147 """ 148 フリマウォッチ判定用 149 re.sub(~)はOLD_SELLとsell_numの数字部分だけを正規表現で抜き出している 150 """151 if re.sub(r"\D", "", OLD_SELL) != re.sub(r"\D", "", sell_num): 152 spreadsheet.sheet1.update_cell(i+1, index_sell+1, str(sell_num))153 # spreadsheet.sheet1.update_cell(i+1, index_watch+1, 'FALSE')154 155 print('販売予定金額 ', sell_num)156 print('フリマウォッチ変更')157 158 print('----------------------------')159
試したこと
バッチファイルを作成して実行してみたり、タスクスケジューラで実行してみたりしましたが結果は変わらず、どこかのタイミングでASINがズレてしまうようです。コードの中にずれない仕組みがあれば良いのかもしれません。
補足情報(FW/ツールのバージョンなど)
Windows11
Anacondaprompt
Python(selenuim等)
ここにより詳細な情報を記載してください。

0 コメント