piyochannnnn
@piyochannnnn

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

pythonでスクレイピングしたデータをスプレッドシートに書き込むときに空欄のセルが入ってしまい詰めたい

解決したいこと

pythonであるページのランキングデータを取得してスプレッドシートへ反映させるときに、空欄が入ってしまうことがあります。
その空欄を上へ詰めて1位から100位まで上から下までスプレッドシートへ反映させたい。

発生している問題・エラー

ランキングが25位おきに4行の空白のセルが入ってしまうことがあります。
空白が入らないページもあります。
スクリーンショット 2021-10-11 16.21.12.png

該当するソースコード

import bs4,requests,time
import gspread
import json
from gspread_dataframe import set_with_dataframe

TIMEOUT = 10
s = 0

URL     =[https://jmda.co.jp/s/genre/drama/?s=1navi, https://jmda.co.jp/s/genre/drama/?s=2navi, https://jmda.co.jp/s/genre/drama/?s=3navi
]
DEFALT_SREEP = 3
HEADER      = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'}

for url in URL:
    try:
        result =requests.get(url,timeout=TIMEOUT,headers=HEADER)
        result.raise_for_status()
        time.sleep(3)

    except Exception as e:

        print('ERROR_DOWNROAD:{}'.format(e))

    else:
        soup    = bs4.BeautifulSoup(result.content, 'html.parser')
        paragraph = soup.select("p.lB-title")
        datas = []

        for p in paragraph:

            datas.append(p.text)


        #ServiceAccountCredentials:Googleの各サービスへアクセスできるservice変数を生成します。
        from oauth2client.service_account import ServiceAccountCredentials

        #2つのAPIを記述しないとリフレッシュトークンを3600秒毎に発行し続けなければならない
        scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']

        #認証情報設定
        credentials = ServiceAccountCredentials.from_json_keyfile_name('spreadsheet-test-rfeu08furiog7.json', scope)

        #OAuth2の資格情報を使用してGoogle APIにログインします。
        gc = gspread.authorize(credentials)

        #共有設定したスプレッドシートキーを変数[SPREADSHEET_KEY]に格納する。
        SPREADSHEET_KEY = 'due8wytqhrjhgf3nqpWTH95woGiTg'

        #ワークブックを取得

        worksheet = gc.open_by_key(SPREADSHEET_KEY).get_worksheet(s)
     s += 1

        # スプレッドシートに書き出す
        cell_list = worksheet.range('E2:E'+str(1+len(datas)))

        #cell_listにtest_listの値を流し込む
        for i,cell in enumerate(cell_list):
            cell.value = datas[i]

        #最後にupdate_cellsで流し込む
        worksheet.update_cells(cell_list)

自分で試したこと

空白を詰めたり、改行を削除する方法を試しましたがうまくいきません。
スプレッドシートでの関数を使って空欄を詰める方法は把握していますが、コードの方で最初から除去したいです。
もし何か思い当たる点があればアドバイスをお願いいたします。

0

3Answer

@bizzpaper さん
cell_listdataszipでまとめて回すと、スプレッドシートには書き込まれずとも、その行は飛ばされて空白になってしまうのではないでしょうか?

2Like

Comments

  1. @piyochannnnn

    Questioner

    ご回答ありがとうございます!
    zipでまとめて回す ということが理解できませんでしたが、そういった現象になるんですね。
    大変参考になりました!

append() でデータを突っ込んでるのであれば、そこで if ではじくか、最後にFilterすればよいのでは?

1Like

Comments

  1. @piyochannnnn

    Questioner

    ご回答ありがとうございます!
    ifではじけました!

@baku2sanさんのおっしゃる通り、datasappendするとき~~、もしくはcellに代入するとき~~にifではじくのが良いかと思います。

  • datasappendするときはじく
for p in paragraph:
	datas.append(p.text)

# 以下のように変更

for p in paragraph:
	if p.text:
		datas.append(p.text)
  • cellに代入するときはじく
for i,cell in enumerate(cell_list):
  cell.value = datas[i]

# 以下のように変更

for cell, data in zip(cell_list, datas):
	if data:
		cell.value = data

ここで、python特有のテクニックがあります。
それはif 変数:です。変数が文字列の場合、空文字であるとFalseと判定されます。これを扱えるようになればコードがぐっとすっきりするので、ぜひ使ってみてください。

判定のされ方について、詳細はこちらをご覧ください。

追記(2021/10/12)

セルではじくと空白行ができちゃいますね。

@Cartelet さん ご指摘ありがとうございました!

1Like

Comments

  1. @piyochannnnn

    Questioner

    ご回答ありがとうございます!
    if ではじくというコードが無知でしたが大変分かりやすくそのまま記述して空欄がなくなりました。

    if 変数: 詳細までいただきありがとうございます!
    正解を知ってから自分のものにしていく勉強法が自分にはあっているので、分かりやすく正解をいただき感謝です。

Your answer might help someone💌