クラスメソッド株式会社データアナリティクス事業本部所属のニューシロです。
今回は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標準ライブラリdatetime
のdatetime.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_1
とpubDate_2
は同じ時刻を表します。並べてみると、pubDate_1
の行末の+0900
はグリニッジ標準時との差を表すことも分かりますね。
- 参照 : グリニッジ標準時
この場合は①のコードでdatetime型にするには少し変更を加えなければなりません。
ほとんど手間はかかりませんが、①②どちらも簡単に処理できるようにPythonサードパーティーライブラリdateutil
のparser.parse
を使用してみます。細かい形式を指定しなくてもdatetime型に変更してくれます。
- 参照 : dateutil
- 参照 : parser.parse
まずはインストールします。
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 エディタ上で起動してみました。
- 参照 : DataFrame からデータを読み込む
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 = "oshiro"
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に格納できそうです。
- 参照 : 協定世界時
補足
dateutil
はGMT
の他にJST
も扱えるのか、pubDate3
を追加し確認しました。
pubDate_3 = "Fri, 21 Apr 2023 15:00:00 JST"
②同様の処理をしました。
結果
↓
ちゃんと+0900
をつけてくれています。大丈夫そうですね。
dateutil
はドキュメントにもあるようにToday is January 1, 2047 at 8:21:00AM
のような曖昧な形式でもdatetime
型に変換してくれるようです。とても便利ですが、業務で使用する場合は仕組みをしっかりと理解してからが良さそうですね。
以上です。ここまでお読みいただきありがとうございました。