質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

コマンド

コマンドとは特定のタスクを行う為に、コンピュータープログラムへ提示する指示文です。多くの場合、コマンドはShellやcmdようなコマンドラインインターフェイスに対する指示文を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2894閲覧

Pythonスクレイピング:コマンドgspreadでのエラーについて

gomasan

総合スコア96

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

コマンド

コマンドとは特定のタスクを行う為に、コンピュータープログラムへ提示する指示文です。多くの場合、コマンドはShellやcmdようなコマンドラインインターフェイスに対する指示文を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/08/12 08:37

編集2020/08/12 09:25

前提・実現したいこと

Pythonを使ってスクレイピングを行い、結果をスプレッドシートへ連携しています。
ライブラリはrequests/BeautifulSoup/gspreadを使っています

発生している問題・エラーメッセージ

VSコードで書いた結果をターミナルで「$ pyhton ファイル名」と実行したところ下記のエラーが出ました。

Traceback (most recent call last): File "/Users/xxx/anaconda3/lib/python3.7/site-packages/gspread/client.py", line 119, in open self.list_spreadsheet_files(title), File "/Users/xxx/anaconda3/lib/python3.7/site-packages/gspread/utils.py", line 97, in finditem return next((item for item in seq if func(item))) StopIteration During handling of the above exception, another exception occurred: Traceback (most recent call last): File "xxx.py", line 9, in <module> wks = gc.open('xxx').sheet1 File "/Users/xxx/anaconda3/lib/python3.7/site-packages/gspread/client.py", line 127, in open raise SpreadsheetNotFound gspread.exceptions.SpreadsheetNotFound

該当のソースコード

Pyhton

1import gspread 2from oauth2client.service_account import ServiceAccountCredentials 3 4scope = ['https://spreadsheets.google.com/feeds', 5 'https://www.googleapis.com/auth/drive'] 6 7credentials = ServiceAccountCredentials.from_json_keyfile_name('xxx.json', scope) 8gc = gspread.authorize(credentials) 9wks = gc.open('xxx').sheet1 10 11wks.update_acell('A1', 'Hello World!') 12print(wks.acell('A1'))

試したこと

  • GoogleAPIでのプロジェクト作成
  • 認証キーの発行(JSONファイル生成)
  • JSONファイルに記載のアドレスをコピーし、スプレッドシートの共有アドレスへペースト、送信
  • VSコードにpythonファイルとJSONファイルを入れる

補足情報(FW/ツールのバージョンなど)

File "/Users/xxx/anaconda3/lib/python3.7/site-packages/gspread/client.py", line 127, in open

とありますが、client.pyは作った記憶がなく、、別のファイルが自動で開かれているなどでしょうか。。
エラーメッセージを色々調べた結果似たものがなかったため質問させていただきました。

ちなみにanaconda,python共にインストールしています。

追記事項

権限についてですが、自分のみになっていたため権限変更を行いました。
メールアドレスで指定できるようでしたので、JSONファイルに記載されていたアドレスを入力しています。
またリンクを知っているユーザー全てが編集できるようにしています。
(ただ、まだ同じエラーになっています。)
イメージ説明

エラーが発生してないシートを確認し、共有ボタンを押すとJSONのアドレスが記載されていました。
ただエラーが発生しているシートはペーストし送信してもここに編集者として出てきません、、

エラーが発生していないシート↓↓
イメージ説明

エラーが発生しているシート↓↓
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nto

2020/08/12 08:47

スプレットシートの編集者権限はどの様になっているでしょうか?
gomasan

2020/08/12 09:09

ありがとうございます。 追加事項に記入しました。 自分のみになっていたため、アドレスを登録かつリンクを知っているユーザー全てが編集できるようにしましたが、まだ同じエラーのままです...
guest

回答1

0

ベストアンサー

遅くなって申し訳御座いません。
同一の環境の構築に時間がかかってしまいました。
が、環境構築以前の問題でした。
以下に修正する事で正常に機能すると思います。

python

1wks = gc.open_by_key(SPREADSHEET_KEY).sheet1

追記

改めて修正致しました。
クラス化してしまい、for文で回すという形を取りました。
大半は前回の追記と変わりませんが、classを使用する事で次のページへの遷移を楽にしました。
次のページへのリンクURLと、現在開いているページURLが異なる(次のページがある)といった場合に
self.pagenum += 1とし、もう一度self.pagedata_createを実行する事で次のページへの遷移を実現しております。

また、件数が膨大になってしまう事を懸念し勝手ながらtqdmで進捗状況を計れる様にしました。
(ご不要の場合にはzip(postdates, comments, reviews)とし、tqdm内オプションを取り外して下さい。)

スプレッドシートへの書き込みですが
API側で書き込みが出来る件数が定められている様です。(通常は100秒に100件まで)
ネット環境にも依存すると思いますがtime.sleep()での制御を任意で調整して下さい。
tqdmによるプログレスバーにて1件あたりの書き込みに何秒が要しているか確認ができます。
1.11.2sec程度になる様に抑えてあげるといいでしょう。
1.0
1.1secで設定するとたまに書き込み制限されてしまいエラーで弾かれてしまいます。

python

1import requests 2from bs4 import BeautifulSoup 3from oauth2client.service_account import ServiceAccountCredentials 4import gspread 5import time 6from tqdm import tqdm 7 8scope = ['https://spreadsheets.google.com/feeds', 9 'https://www.googleapis.com/auth/drive'] 10credentials = ServiceAccountCredentials.from_json_keyfile_name('ファイル名.json', scope) 11gc = gspread.authorize(credentials) 12SPREADSHEET_KEY = 'スプレッドシートキー' 13worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1 14domain = 'https://furunavi.jp' 15 16 17class Main: 18 def __init__(self, pageid): 19 self.pageid = pageid 20 self.pagenum = 1 21 22 def pagedata_create(self): 23 domain = 'https://furunavi.jp' 24 url = '{}/review_list.aspx?pid={}&p={}'.format(domain, self.pageid, self.pagenum) 25 res = requests.get(url) 26 self.soup = BeautifulSoup(res.content, 'html.parser') 27 self.query = res.url[len(domain):] 28 if not self.soup.find('li', string='レビューの投稿はありません'): 29 self.spread_writes() 30 31 32 def spread_writes(self): 33 elems = ["#breadcrumb ul.cf li:nth-of-type(3)", "#breadcrumb ul.cf li:nth-of-type(4)", 34 '.review_review_text', '.review_info', ".product_rep"] 35 36 elements = [self.soup.select(e) for e in elems] 37 area = elements[0][0].string 38 item = elements[1][0].string 39 postdates = elements[3] 40 comments = elements[2] 41 reviews = elements[4] 42 cnt = 1 43 for pd, cmt, rv in tqdm(zip(postdates, comments, reviews), total=len(postdates), desc=f'id{self.pageid} page{self.pagenum} writing', leave=False): 44 rv = rv.i["class"][0].replace('rep_','').replace('_','.') 45 datas = [area, item, pd.text, cmt.text, rv] 46 worksheet.append_row(datas) 47 time.sleep(0.8) 48 49 if self.soup.find('a', string='次へ').get('href') != self.query: 50 self.pagenum += 1 51 self.pagedata_create() 52 53for i in range(73086, 73099): 54 main = Main(i) 55 main.pagedata_create() 56 print(f'{i} Done!') 57print('Finished!')

投稿2020/08/12 10:54

編集2020/08/13 06:13
nto

総合スコア1438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gomasan

2020/08/12 13:26

今回もご丁寧にありがとうございます...! 無事スプレッドシートに反映しました...TT またappend_row()のやり方も教えてくださりありがとうございます!!今まで引っかかっていたものがスムーズにいくようになりました、、大変感謝しております。。
nto

2020/08/12 15:07

肝心な次のページの遷移の実装を忘れていたので改めて明日追加いたしますね。
gomasan

2020/08/13 13:30

コメント見落としており申し訳ございません、、 次のページの遷移が量が膨大になるためキャンセルとなりました。 今はそれぞれの商品口コミの1ページ目だけを参照するように作っております! また、分からないところがあれば質問させていただきます。 本当にありがとうございます。
nto

2020/08/13 16:53

そうでしたか。 その場合は本日更新したコードの49~51行目をコメントアウトしていただくことでそのまま次ページへの遷移は無しで運転できるかと思います。 実はスプレッドシート関連のモジュールの使用は初めてだった為こちらとしても勉強になりました。
gomasan

2020/08/14 09:58

かしこまりました。 ありがとうございます!!とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問