[初心者向け]RSSのpubDateをPythonでdatetime型に変換してBigQueryにロードしてみた

PythonでRSSのpubDateをdatetime型に変換してみました。BigQueryにロードもします。
2023.05.01

クラスメソッド株式会社データアナリティクス事業本部所属のニューシロです。
今回はRSSを取得すると得られるpubDateについて、Pythonを用いてdatetime型に変換し、BigQueryにロードするまでを書いてみました。

前提

この記事で説明すること

  • PythonでRSSのpubDateをdatetime型に変換する方法①(datetime.strptime)
  • PythonでRSSのpubDateをdatetime型に変換する方法②(dateutil.parser)
  • BigQueryへロードした結果

この記事で説明しないこと

  • RSSの取得方法
  • Pythonを用いたBigQueryへのロードについての細かい内容

本題

RSS2.0ではデータを取得した際に日付がpubDateで与えられます。

pubDate_1 = "Fri, 21 Apr 2023 15:00:00 +0900"

このままBigQueryにロードしてもSTRING型になってしまいますので、扱いづらいです。datetime型に変換してみましょう。

① Python標準ライブラリのdatetimeを使用する

Python標準ライブラリdatetimedatetime.strptimeを使用します。
datetime.strptimeは文字列からdatetime型を生成することが可能です。

例えばFri%aというように、pubDateの表記に合わせてコードを書いていきます。

date_time_1 = datetime.strptime(pubDate_1, "%a, %d %b %Y %H:%M:%S %z")

対応する書式は以下のリンクにあります。

これを用いた以下のコードを実行します。

from datetime import datetime


pubDate_1 = "Fri, 21 Apr 2023 15:00:00 +0900"

# strptimeでdatetime型に変換
date_time_1 = datetime.strptime(pubDate_1, "%a, %d %b %Y %H:%M:%S %z")

# 元の文字列
print(f"pubDate : {pubDate_1}")
# 変換後
print(f"datetime: {date_time_1}")
# 変換後のデータ型
print(type(date_time_1))

結果

datetime型になっていますね。 typeでもdatetime型になっていることがわかります。

② Pythonサードパーティーライブラリのdateutilを使用する

先ほどのpubDate_1に加えて新たにpubDate_2について考えます。

pubDate_1 = "Fri, 21 Apr 2023 15:00:00 +0900"
pubDate_2 = "Fri, 21 Apr 2023 06:00:00 GMT"

pubDate_2は先ほどと表記が違い、行末にGMTがついております。 取得先のRSSによって、どちらのパターンかは変わってきます。
GMTはグリニッジ標準時を表しますので、日本時間にするには時差の9時間を足します。よって、pubDate_1pubDate_2は同じ時刻を表します。並べてみると、pubDate_1の行末の+0900はグリニッジ標準時との差を表すことも分かりますね。

この場合は①のコードでdatetime型にするには少し変更を加えなければなりません。
ほとんど手間はかかりませんが、①②どちらも簡単に処理できるようにPythonサードパーティーライブラリdateutilparser.parseを使用してみます。細かい形式を指定しなくてもdatetime型に変更してくれます。

まずはインストールします。

pip install python-dateutil

以下のコードを実行します。

from dateutil import parser


pubDates = [
    "Fri, 21 Apr 2023 15:00:00 +0900",
    "Fri, 21 Apr 2023 06:00:00 GMT"
]

for pubDate in pubDates:

    # dateutilのparser.parse使用
    date_time = parser.parse(pubDate)

    # 元の文字列
    print(f"pubDate : {pubDate}")
    # 変換後
    print(f"datetime: {date_time}")
    # 変換後のデータ型
    print(type(date_time))
    print("----------")

結果

こちらもdatetime型になっていることが確認できました。

BigQueryへ格納する

datetime型には変換できているので、BigQueryへロードしてみます。 テーブルはあらかじめ作成しておきます。

タイムゾーンを考慮させるため、datetimeのデータ型はTIMESTAMPを指定します。

csvに出力してコンソール上からでもBigQueryへロードはできるのですが、ETL処理等での活用も考えて今回はコードを書いてみます。pandasでデータフレームを作成しBigQueryへロードします。 以下のリンクを参考にしています(コード内容の細かい説明は割愛します)。ちなみにGoogle CloudのサービスであるCloud Shell エディタ上で起動してみました。  

from dateutil import parser
from google.cloud import bigquery
import pandas as pd


pubDates = [
    "Fri, 21 Apr 2023 15:00:00 +0900",
    "Fri, 21 Apr 2023 06:00:00 GMT"
]

# dataframe用の配列
records = []

for pubDate in pubDates:

    # dateutilのparser.parse使用
    date_time = parser.parse(pubDate)

    # dataframe用の配列に追加
    records.append({
        "pubDate": pubDate,
        "datetime": date_time
    })

# dataframe作成
df = pd.DataFrame(records, columns=["pubDate", "datetime"])

# BigQueryへロードする
client = bigquery.Client()
project_id = "newshiro"
table_id = "developersio.pubdate-datetime"
job_config = bigquery.LoadJobConfig(
    schema=[
        bigquery.SchemaField("pubDate", "STRING"),
        bigquery.SchemaField("datetime", "TIMESTAMP"),
    ]
)
job = client.load_table_from_dataframe(
    df, table_id, job_config=job_config
)
job.result()

結果

BigQueryのTIMESTAMP型はデフォルトでUTC形式で格納されるようになっています。UTCは「協定世界時」といい,GMTとほぼ同じ扱いです。結果をみると、2行とも全く同じ時刻として格納されていますね。RSSのpubDateは①か②を使えばうまくBigQueryに格納できそうです。

補足

dateutilGMTの他にJSTも扱えるのか、pubDate3を追加し確認しました。

pubDate_3 = "Fri, 21 Apr 2023 15:00:00 JST"

②同様の処理をしました。

結果

ちゃんと+0900をつけてくれています。大丈夫そうですね。
dateutilはドキュメントにもあるようにToday is January 1, 2047 at 8:21:00AMのような曖昧な形式でもdatetime型に変換してくれるようです。とても便利ですが、業務で使用する場合は仕組みをしっかりと理解してからが良さそうですね。

以上です。ここまでお読みいただきありがとうございました。

引用・参照まとめ