前提・実現したいこと
後述の、とあるサイトの商品別の販売集計表をスクレイピングしたいのですが、値がとれずに困っています。
環境
-
Python 3.9.0
-
Windows 10 Pro
-
google chrome
-
Beautifulsoup
-
requests
-
selenium
-
chrome ドライバ
(google chrome以下のものは、いずれも最新版です)
発生している問題
下記のようなテーブルの「最高値(円)」「平均値(円)」「最安値(円)」「実勢価格(円)」の各値がとれません。
※ 掲載にあたり、一部内容を伏せるために項目名や項目値を加工しております。ご容赦ください。
テーブルの構造
・ 実際には、商品名=商品1とその直下の「a00001」(商品コード)は、同じ行で定義されています。(下記HTMLソースをご参照ください。)
・ また、商品10件ごとにヘッダー項目が挿入されており、これが1ページあたり5組もある大きなテーブルです。
・ ページ内に<table>
タグで囲まれた箇所は、このテーブルのみです。
・ さらに、このテーブルの内容(明細)は、全体でおおよそ100ページ分ほどあります。
商品名 | 最高値(円) | 平均値(円) | 最安値(円) | 実勢価格(円) | 販売開始日 | 販売数(単位) | 累積販売金額(円) |
---|---|---|---|---|---|---|---|
商品1 | 90.0 | 91.5 | 93.0 | 92.0 | 1999/1/19 | 1,565,432 | 173,452,222,567 |
a00001 | (12/7) | (12/8) | (12/13) | (枚) | (円) | ||
商品2 | 80.0 | 81.5 | 83.0 | 82.0 | 1999/7/21 | 1,868,432 | 423,452,288,590 |
a00002 | (12/7) | (12/13) | (12/8) | (12/13) | (枚) | (円) | |
(...略...) | |||||||
商品名 | 最高値(円) | 平均値(円) | 最安値(円) | 実勢価格(円) | 販売開始日 | 販売数(単位) | 累積販売金額(円) |
商品11 | 90.0 | 91.5 | 93.0 | 92.0 | 1999/1/19 | 1,565,432 | 173,452,222,567 |
a00011 | (12/7) | (12/13) | (12/8) | (12/13) | (枚) | (円) | |
(...略...) |
html
1<html> 2<head> 3(...略...) 4<body> 5(...略...) 6 7<table cellspacing="0" class="cmn-table"> 8 <thead> 9 <tr> 10 <th class="cmn-table_a">商品名</th> 11 <th class="cmn-table_b">最高値(円)</th> 12 <th class="cmn-table_c">平均値(円)</th> 13 <th class="cmn-table_d">最安値(円)</th> 14 <th class="cmn-table_e">実勢価格(円)</th> 15 <th class="cmn-table_f">販売開始日</th> 16 <th class="cmn-table_g">販売数(単位)</th> 17 <th class="cmn-table_h">累積販売金額(円)</th> 18 </tr> 19 </thead> 20 <tbody> 21 <tr> 22 <th class="cmn-table_th"> 23 <a href="/item/?itemcode=a00001" title="商品名1の情報">商品1<span>a00001</span></th> 24 <td class="cmn-item"> 25 90.0<span>(12/7)</span> 26 </td> 27 <td class="cmn-item"> 28 91.5<span>(12/13)</span> 29 </td> 30 <td class="cmn-item"> 31 93.0<span>(12/8)</span> 32 </td> 33 <td class="cmn-item"> 34 92.0<span>(12/13)</span> 35 </td> 36 <td class="cmn-item"> 37 1999/1/19 38 </td> 39 <td class="cmn-item"> 40 1,565,432<span>(kL)</span> 41 </td> 42 <td class="cmn-item"> 43 173,452,222,567<span>(円)</span> 44 </td> 45 </tr> 46 <tr> 47 <th class="cmn-table_th"> 48 <a href="/item/?itemcode=a00002" title="商品名2の情報">商品2<span>a00002</span></th> 49 <td class="cmn-item"> 50 80.0<span>(12/7)</span> 51 </td> 52 <td class="cmn-item"> 53 81.5<span>(12/13)</span> 54 </td> 55 <td class="cmn-item"> 56 83.0<span>(12/8)</span> 57 </td> 58 <td class="cmn-item"> 59 82.0<span>(12/13)</span> 60 </td> 61 <td class="cmn-item"> 62 1999/7/21 63 </td> 64 <td class="cmn-item"> 65 1,868,432<span>(kL)</span> 66 </td> 67 <td class="cmn-item"> 68 423,452,288,590<span>(円)</span> 69 </td> 70 </tr> 71 72 (...略...) 73 74 </tbody> 75</table> 76 77(...略...) 78</body> 79</html>
該当のソースコード
試したこと
まずは、1ページ目の1行目だけでもとろうと思い、以下のようなコーディングをしました。
商品名と商品コードはとれましたが、最高値から累積販売金額までは、該当するタグが「<td class="cmn-item">」で同一です。
td
タグに対して、2カラム目(「平均値(円)」)以降はnext_sibling
を指定してみましたが、「最高値(円)」「平均値(円)」「最安値(円)」「実勢価格(円)」のうち、最初の「最高値(円)」しかとれませんでした。
どのように指定すれば、「平均値(円)」「最安値(円)」「実勢価格(円)」の金額もとることが出来るでしょうか。
ご教示ください。
※上記4項目の日付については取得不要です。
python
1import sys 2import csv 3import datetime 4import requests 5 6from bs4 import BeautifulSoup 7from selenium import webdriver 8from selenium.webdriver.chrome.options import Options 9from time import sleep 10 11csv_date = datetime.datetime.today().strftime("%Y%m%d") 12csv_file_name = "stock_week_price_" + csv_date + ".csv" 13f = open(csv_file_name, "w", encoding="CP932", errors="ignore") 14 15writer = csv.writer(f, lineterminator="\n") 16csv_header = ["商品コード","商品名","最高値","平均値","最安値","実勢価格"] 17writer.writerow(csv_header) 18 19options = Options() 20driver = webdriver.Chrome('C:/Program Files/chromedriver_win32/chromedriver', options=options) 21 22url = "https://www.exzample.com/historical/?p=1" 23 24driver.get(url) 25res = requests.get(url) 26 27sleep(1) 28 29soup = BeautifulSoup(res.content, "lxml") 30 31soup.find('table') 32table = soup.find('table') 33 34csvlist = [] 35 36table.find('a').text 37a = table.find('a').text 38stock_code = a[-6:] 39stock_name = a[:-6] 40 41csvlist.append(item_code) 42csvlist.append(item_name) 43 44table.find('td').text 45td1 = table.find('td').text 46high_price = td1.split('(')[0] 47csvlist.append(high_price) 48 49table.td.next_sibling 50td2 = table.td.next_sibling 51average_price = td2.split('(')[0] 52csvlist.append(average_price) 53 54table.td.next_sibling 55td3 = table.td.next_sibling 56low_price = td3.split('(')[0] 57csvlist.append(low_price) 58 59table.td.next_sibling 60td4 = table.td.next_sibling 61actual_price = td4.split('(')[0] 62csvlist.append(actual_price) 63 64writer.writerow(csvlist) 65 66f.close() 67driver.close() 68 69sys.exit()
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/15 05:14
退会済みユーザー
2020/12/15 05:21
2020/12/15 05:59
退会済みユーザー
2020/12/15 06:47 編集
2020/12/15 08:00
退会済みユーザー
2020/12/15 08:47 編集
退会済みユーザー
2020/12/15 08:55 編集
2020/12/15 08:56
退会済みユーザー
2020/12/15 09:07
2020/12/15 09:11