前提・実現したいこと
Pythonでwebサイトのスクレイピングをし、csvに抽出しています。
前回抽出していないものを抽出し、csvに書き込むということをしたいです。
(本来は昨日の日付で抽出したいのですが、数日後に口コミ反映がされる場合が多いため、「抽出したことがないもの」という条件に切り替えています。)
下の内容でいうと、
・全商品の最終投稿日付(last_update_list)を取得
・次プログラムを回すときにlast_update_listを参照して、追記するレビューリストを作成
・last_update_listを保存・読み込み
発生している問題・エラーメッセージ
pickleを使って前回内容を記憶、読み出しをしようと思っているのですが、うまくいきません。。
Traceback (most recent call last): File "/Users/myname/Desktop/sample.py", line 136, in <module> main(False) File "/Users/myname/Desktop/sample.py", line 30, in main pickle.load(fl) _pickle.UnpicklingError: invalid load key, 'f'.
以下にコード全体を記載しますが、エラー箇所は以下の通りです。
line30 pickle.load(fl) line136(コードの最終行) main(False)
該当のソースコード
sample.py
python
1 2from selenium import webdriver 3import time 4import csv 5import re 6from datetime import datetime, date, timedelta 7from selenium.webdriver.common.keys import Keys 8from selenium.webdriver.chrome.options import Options 9import sys 10import pickle 11 12 13def str2date(date_str): 14 result = re.search(r'(\d{4})年(\d{1,2})月(\d{1,2})日', date_str) 15 tar_date = datetime(int(result[1]), int(result[2]), int(result[3])) 16 return tar_date 17 18def is_bf_yesterday(tar_date, last_update_date): 19 # now = datetime.now() 20 # yesterday = now - timedelta(days=1) 21 last_update_date_str = datetime.strftime(last_update_date, '%Y-%m-%d') 22 tar_date_str = datetime.strftime(tar_date, '%Y-%m-%d') 23 24 return tar_date_str > last_update_date_str 25 26def main(is_init): 27 28 # rbモードでファイルを読み込み 29 fl = open('pickle.binaryfile','rb') 30 pickle.load(fl) 31 # csv_file_name 32 csv_file_name = "/Users/myname/Desktop/" + "satofuru" + ".csv" 33 f = open(csv_file_name, 'a',encoding='cp932', errors='ignore') 34 35 #ファイルへの書き込み 36 writer = csv.writer(f, lineterminator='\n') 37 38 #headerの指定 39 csv_header = ["商品名", "投稿日","評価", "レビュー"] 40 writer.writerow(csv_header) 41 42 # ブラウザを開く 43 last_update_dict = {} 44 browser = webdriver.Chrome('/usr/local/bin/chromedriver') 45 for page in range(1, 4): 46 print('webdriver ok') 47 # URLを開く 48 url = "https://www.xxx.php?=60&p={}".format(page) 49 browser.get(url) 50 time.sleep(1.0) 51 elems = browser.find_elements_by_class_name('ItemList__link') 52 contain_review_links = [] 53 review_links = [] 54 date_src_list = [] 55 for elem in elems: 56 #各elemからimgタグのsrcを一覧で出す 57 review_score_src = elem.find_element_by_class_name('ItemList__xxx').find_element_by_tag_name('img').get_attribute('src') 58 if review_score_src == 'https://www.xxx.jp/static/xxx/images/pic_star0.png': 59 pass 60 else: 61 # リンクを一覧で取得 62 contain_review_links.append(elem.get_attribute('href')) 63 64 for contain_review_link in contain_review_links: 65 time.sleep(1.0) 66 browser.get(contain_review_link) 67 review_list_src = browser.find_element_by_css_selector('.xxx').get_attribute('href') 68 browser.get(review_list_src) 69 time.sleep(2.0) 70 71 pr_name = browser.find_element_by_css_selector('.xxx').text 72 73 review_table = browser.find_elements_by_css_selector('.xxx')[2] 74 75 review_lists = review_table.find_elements_by_css_selector('tr')[1:] 76 for i, review_list in enumerate(review_lists): 77 # review_listで投稿日が昨日であれば、「続きを読む」のリンクを取得してcsvに抽出する 78 review_lists_date = review_list.find_elements_by_css_selector('td')[0].text 79 date_src_list.append(review_lists_date) 80 for date_src in date_src_list: 81 elem_date = str2date(date_src) 82 if is_init: 83 if i == 0: 84 last_update_dict[pr_name] = elem_date 85 review_link_list = review_list.find_element_by_css_selector('a').get_attribute('href') 86 review_links.append(review_link_list) 87 elif is_bf_yesterday(elem_date, last_update_dict[pr_name]): 88 # 昨日の日付の場合はhrefリンクを取得し、リストにする(review_links) 89 review_link_list = review_list.find_element_by_css_selector('a').get_attribute('href') 90 review_links.append(review_link_list) 91 92 93 94 for review_link in review_links: 95 print('review_link ok') 96 csv_list = [] 97 time.sleep(2.0) 98 browser.get(review_link) 99 elem_product_name = browser.find_element_by_css_selector('.product-name a') 100 product_name = elem_product_name.text 101 review_box = browser.find_element_by_css_selector('.review_info') 102 review_elems = review_box.find_elements_by_css_selector('tr td') 103 review_date = review_elems[0].text 104 review_score = 0 105 imgs = review_box.find_elements_by_css_selector('.valuation img') 106 for img in imgs: 107 src = img.get_attribute("src") 108 if src == 'https://www.xxx.jp/xxx/images/common/star_a.png': 109 review_score += 1 110 review = review_box.find_element_by_css_selector('.cxxx').text 111 csv_list.append(product_name) 112 csv_list.append(review_date) 113 csv_list.append(review_score) 114 csv_list.append(review) 115 writer.writerow(csv_list) 116 117 f.close() 118 browser.close() 119 120if __name__ == "__main__": 121 if len(sys.argv) >= 2: 122 if sys.argv[1] == 'init': 123 main(is_init=True) 124 else: 125 main(False)
pickle.binaryfile
fl = open('pickle.binaryfile','wb') pickle.dump(last_update_dict, fl) fl.close
試したこと
pythonファイルのmain関数でまず読み込みをし、その結果をpickle.binaryfileで保存(したつもりです..)
pickleを今回初めて使いまして、使い方が全然違うかもしれません...
アドバイスいただけますと幸いです。よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー