質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

Google Cloud Storage

Google Cloud Storageは、グーグル社が提供しているクラウドベースのデベロッパー・企業向けストレージサービス。可用性に優れ、APIで操作可能なため、データのアーカイブ保存やアプリケーションのコンテンツ提供など様々な用途に活用できます。

App Store

App Storeは、Apple社が運営する、iPhone、iPod touch、iPad向けアプリケーションソフトのダウンロードサービスです。携帯電話、Wi-Fiによる無線通信に対応しており、多くのアプリケーションをダウンロード、インストールすることができます。世界中の開発者によってアプリケーションが登録されており、有償のソフトもあればフリーソフトも多く登録されています。

Q&A

0回答

157閲覧

App Store Connect API から取得したデータをBigQueryに格納できない

nsuda

総合スコア0

BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

Google Cloud Storage

Google Cloud Storageは、グーグル社が提供しているクラウドベースのデベロッパー・企業向けストレージサービス。可用性に優れ、APIで操作可能なため、データのアーカイブ保存やアプリケーションのコンテンツ提供など様々な用途に活用できます。

App Store

App Storeは、Apple社が運営する、iPhone、iPod touch、iPad向けアプリケーションソフトのダウンロードサービスです。携帯電話、Wi-Fiによる無線通信に対応しており、多くのアプリケーションをダウンロード、インストールすることができます。世界中の開発者によってアプリケーションが登録されており、有償のソフトもあればフリーソフトも多く登録されています。

0グッド

0クリップ

投稿2024/04/17 23:58

編集2024/04/23 05:19

実現したいこと

List All Customer Reviews for an App(アプリのすべての顧客レビューをリストする)

のデータを、BigQueryテーブルに格納したいが、エラーが出てしまうので解決したい。

発生している問題・分からないこと

特殊文字が含まれてることによる文字化けが原因かと仮定し、下記検証。
他原因は現状思いついていません。

① 特殊文字を削除したい。
→いろんな場所に .decode('utf-8','replace') を付与して試したが、意図した状態にならない。
また、.decode('cp932','replace') に敢えて変換し特殊文字が消えることを期待したがこちらもうまくいかず。

② 出力時に 'Content-Type': 'text/html; charset=utf-8' にしたい。
→現状、バケットのファイルのページでContent-Type欄に
text/html; charset=utf-8
を手入力する必要がある。

※補足:
API経由でデータをバケットに格納すること自体は出来ている。

<実装状況>
Apple Developer API から連携
→ Google Cloud Function で読み込み
→ Google Cloud Storage に保存
→ Google BigQuery Studio でテーブルに書き出し ★読み込み不可

エラーメッセージ

error

1Error while reading data, error message: CSV table encountered too many errors, giving up. Rows: 37; errors: 100. Please look into the errors[] collection for more details. File: gs://[バケット名]/[ファイル名].csv.gz

該当のソースコード

import base64 import logging, os, sys, re import pprint import datetime import urllib.request,urllib.error from google.cloud import storage import jwt import time from google.cloud import secretmanager from google.oauth2 import service_account import json # JWTトークンの生成 ### 省略 ### # APIからレポートを取得 def __get_reports(token,date_str=None): base_url = 'https://api.appstoreconnect.apple.com/v1/apps/xxxxxxxx/customerReviews' #ダミー値 vendor_number = xxxxxxxx #ダミー値 if not date_str: jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST') date_str = (datetime.datetime.now(jst) - datetime.timedelta(days=2)).strftime('%Y-%m-%d') path_parameters = { "id" : xxxxxxxx #ダミー値 } query_parameters = { } url = base_url headers = {'Authorization': 'Bearer ' + token,'Accept': '*/*'} req = urllib.request.Request('{}?{}'.format(url, urllib.parse.urlencode(query_parameters)), headers=headers) try: with urllib.request.urlopen(req) as res: content = res.read() print("done") #デバッグ code = 200 except (urllib.error.HTTPError, urllib.error.URLError) as e: logging.error("Error occered in urllib.request.Request().\n code: " + str(e.code) + \ "\n reason: " + e.reason) code = e.code content = e.reason print("error") #デバッグ return (code, content, date_str) # Cloud Storageにレポートを格納 def __write_to_gcs(content,filename): storage_client = storage.Client() bucket_name = 'xxxxxxxx' #ダミー値 bucket = storage_client.get_bucket(bucket_name) blob = bucket.blob(filename) blob.upload_from_string(content) def get_apple_reports(request): token = __get_apple_store_connect_api_token() vendor_number = 'xxxxxxxx' date_str = None (code, content, date_str) = __get_reports(token, date_str) filename = date_str + '.csv.gz' __write_to_gcs(content,filename) return (None,200,None) def get_customer_reviews(event, context): request = {"args": {"date_str": None}} get_apple_reports(request)

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

取り込めない理由はエラー文から断定はできない。
仮説通り特殊文字のせいだとするならば、具体的に引っかかっていると推測している文字は「●」で、出力結果に残ってしまう。
恐らくこの文字↓
https://lets-emoji.com/black-circle-emoji/

補足

print("done") の代わりに、
print(res.msg.as_string()) や print(ascii(content))を入れた結果のログ:

{ insertId: "***" logName: "projects/***/logs/cloudaudit.googleapis.com%2Factivity" operation: { first: true id: "operations/***" producer: "cloudfunctions.googleapis.com" } protoPayload: { @type: "type.googleapis.com/google.cloud.audit.AuditLog" authenticationInfo: { principalEmail: "***@***" } authorizationInfo: [ 0: { granted: true permission: "cloudfunctions.functions.update" permissionType: "ADMIN_WRITE" resource: "projects/***" resourceAttributes: { }}] methodName: "google.cloud.functions.v1.CloudFunctionsService.UpdateFunction" request: { @type: "type.googleapis.com/google.cloud.functions.v1.UpdateFunctionRequest" function: { availableMemoryMb: 2048 dockerRegistry: "CONTAINER_REGISTRY" entryPoint: "***" eventTrigger: { eventType: "google.pubsub.topic.publish" resource: "projects/***" } ingressSettings: "ALLOW_INTERNAL_ONLY" maxInstances: 1 name: "projects/***" runtime: "python311" serviceAccountEmail: "***@***" sourceUploadUrl: "https://storage.googleapis.com/***" timeout: "120s" } updateMask: "sourceUploadUrl" } requestMetadata: { callerIp: "***" callerSuppliedUserAgent: "***" destinationAttributes: { } requestAttributes: { auth: { } time: "2024-04-23T05:07:04.513356Z" }} resourceLocation: { currentLocations: [ 0: "***" ]} resourceName: "projects/***" serviceName: "cloudfunctions.googleapis.com" } receiveTimestamp: "2024-04-23T05:07:04.756380944Z" resource: { labels: { function_name: "***" project_id: "***" region: "***" } type: "cloud_function" } severity: "NOTICE" timestamp: "2024-04-23T05:07:03.340489Z"}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nsuda

2024/04/18 08:02

ありがとうございます。 コードを直接書くことに抵抗があり控えてしまいましたが、マスク化して更新いたしました。 ご存じのことがあれば、お知恵お借りできましたら嬉しいです。
ikedas

2024/04/18 09:30

特殊文字のせいだと決めつける前に、現状を把握しましょう。 ・エラーメッセージは要約や省略をせず、出力された内容全てを掲載してください。通常は1行だけということはないです。 ・コード中の > with urllib.request.urlopen(req) as res: のところで、 res.msg.as_string() の値がどんな内容になっているか見せてもらえませんか。 ・またこの箇所で content に res.read()の値を代入していますが、このとき ascii(content) の値がどんな内容か見せてもらえませんか (これは結構長くなると思うので、全部でなくても最初の方だけ見せてもらえればいいです)。 ちなみに、以上のことはこのコメント欄に書くのではなく、質問文を編集して書いてください。
nsuda

2024/04/22 09:44

遅くなりすみません、コメントありがとうございます。 ■エラーメッセージ ・バケットからBQに取り込むときにのみエラーメッセージが発生しており、  エラーメッセージも貼った部分で全てになります。伏せたところ以外は特に省略していません。 ■with urllib.request.urlopen(req) as res のところ すみません、 res.msg.as_string() の関数がそもそも入っていませんでした・・・! ■res.read()の値の代入 ascii(content) も特に記載していませんでした・・・! Apple Connect API で別のコンテンツは連携できておりそちらのコードを参考にしているのですが 現在使用しているコードの中で ascii で引っかる部分が #headers = {'Authorization': 'Bearer {}'.format(token.decode('ascii')),'Accept': '*/*'} と、コメントアウトされているため特に指定がなされていませんでした。 ということで本文が特に更新できませんでした、、、 これらの情報でおわかりのことがあれば、教えていただけますととても嬉しいです。
ikedas

2024/04/22 14:46 編集

> の関数がそもそも入っていませんでした・・・! > ascii(content) も特に記載していませんでした・・・! ちょっと言っている意味がわからないのですが、私が言いたかったのは、 コード中に print(res.msg.as_string()) とか print(ascii(content)) とかいったコードを挿入して、実行したときにコンソールに何が表示されるか確認してもらえませんか。 ということです。
nsuda

2024/04/23 05:21

ご回答ありがとうございます。 この手の業務に慣れておらず、コメントの意図を汲めず失礼しました。 無い知識で無理やり対応したため、イメージされている情報が表示されているかわかりませんが 補足欄に追記しました。分かることがあれば良いのですが・・・。 何卒よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問