スクレイピングで頻出するのは
開始日と終り日を入力
開始日から終わり日までループしながらなにかしらのデータを取得するというもの。
頻出のわりにはぴたっとはまるものがなかったのでメモ書き
http://test.jp?xx=202112
http://test.jp?xx=202201
のようにxx=202201のクエリパラメータ部分を動的に変更することで、各月のデータを取得する。
例えば
開始:2021/11/01
終了:2022/2/28
の場合
年月を表す文字列を以下のように順次作成し、
202111
202112
202201
202202
作成した文字列をクエリパラメータにして順次ページ遷移する
vbaの場合
前提
windows10
①DateDiff 関数でループに必要な月の差分を求める。
例・開始が2021年11月10日終了が2022年2月1日の場合、4か月
DateDiff関数使い方
②必要な月数だけループする
③ループ処理中でDateAdd関数を使い、開始月から1か月づつ足す。
④ ③で作成した日付型のデータをFormat関数でクエリパラメータ用に成形する
以下サンプル
開始日を2021/10/30 終了日を2022/2/28と設定
動的にパラメータを設定したいURLをhttps://test?xx=
したので、
https://test?xx=202110
https://test?xx=202111
https://test?xx=202112
https://test?xx=202201
https://test?xx=202202
とコンソールに出力される。
Sub test()
'開始日と終わり日を設定する
Dim STARTDAY As String: STARTDAY = "2021/10/30"
Dim LASTSDAY As String: LASTDAY = "2022/2/28"
Dim mm As Long 'forループで使う
Dim hizukemozi As Date '1か月後の日付
Dim para As String 'クエリパラメータ用に成形する
Dim url As String: url = "https://test?xx=" 'クエリパラメータを使ってURLを動的に作成する
'月の分だけループする
For mm = 0 To DateDiff("m", STARTDAY, LASTDAY)
hizukemozi = DateAdd("m", mm, STARTDAY) '開始日に1月ずつ足す
para = Format(hizukemozi, "yyyymm") '日付を成形する
Debug.Print (url & para) '日付部分を動的に変更できた。
Next mm
End Sub
Pythonの場合
vbaをそのまま翻訳すればいいかと思いきや・・・
vbaのDateDiff関数に相当する関数を見つけることができなくて
地味に面倒でした。
①月で計算するにはdateutil.relativedataを使うのが簡単
インストールされていない場合は以下でインストール。
windowsの場合
py -m pip install python-dateutil
(注)python-dateutil コピペしたときに入れ替わってしまったのか、
python-dateutilとハイフンが全角になっていて。
pipインストール時にエラー。無駄な時間を過ごしました。
②strptime関数を使い日付文字列を日付型に変更する
③開始日と終了日の月の差分を求める
VBAのDateDiff関数に相当するものを見つけることができなかったので
年と月それぞれでに引き算しました。
④必要な月数だけループ処理する
⑤dateutil.relativedelta関数でループ中の開始月に1か月づつ足していく
(注)relativedelta(months=i) の months=i monthの末尾にsがつく場合と month=iのように末尾にsがつかない場合意味が違います。
最初month=iにしていたため、年をまたいだ処理ができなくて無駄な時間を過ごしました。
monthsのように末尾にsがつくと相対参照になるらしいです。
今回はmonths=iとsがつくのが正解
import datetime
from dateutil.relativedelta import relativedelta
if __name__ == '__main__':
startday="2021/10/30" #開始日
lastday="2022/2/28" #終了日
url = "https://test?xx=" #日付のパラメータを追加するURL
#開始日終了日を日付型にする
startday=datetime.datetime.strptime(startday,"%Y/%m/%d")
lastday = datetime.datetime.strptime(lastday,"%Y/%m/%d")
#開始日と終了日の月の差分を取得する
sabun = (lastday.year-startday.year)*12+lastday.month-startday.month
for i in range(0,sabun+1):
start = startday #開始日を設定する
loop=start+relativedelta(months=i) #開始日に1か月づつ加算する
para = loop.strftime("%Y%m") #日付型データをクエリパラメータ用データに成形する
print(url+para)