LoginSignup
1
0

More than 1 year has passed since last update.

月でループする(クエリパラメータを動的に作成) VBA Python

Posted at

スクレイピングで頻出するのは
開始日と終り日を入力
開始日から終わり日までループしながらなにかしらのデータを取得するというもの。

頻出のわりにはぴたっとはまるものがなかったのでメモ書き

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か月づつ足す。

DateAdd関数使い方

④ ③で作成した日付型のデータをFormat関数でクエリパラメータ用に成形する

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
とコンソールに出力される。

vba

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の場合

python
py -m pip install python-dateutil

(注)python-dateutil コピペしたときに入れ替わってしまったのか、
python-dateutilとハイフンが全角になっていて。
pipインストール時にエラー。無駄な時間を過ごしました。

dateutil.relativedata解説

②strptime関数を使い日付文字列を日付型に変更する

strptime関数解説

③開始日と終了日の月の差分を求める

VBAのDateDiff関数に相当するものを見つけることができなかったので
年と月それぞれでに引き算しました。

④必要な月数だけループ処理する

⑤dateutil.relativedelta関数でループ中の開始月に1か月づつ足していく

dateutil.relativedelta関数解説

(注)relativedelta(months=i) の months=i monthの末尾にsがつく場合と month=iのように末尾にsがつかない場合意味が違います。
最初month=iにしていたため、年をまたいだ処理ができなくて無駄な時間を過ごしました。
monthsのように末尾にsがつくと相対参照になるらしいです。
今回はmonths=iとsがつくのが正解

python
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)        

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0