在第三章 [Downloading, Reading and Understanding Sales and Trends Data] 有提到一個 Auto-Ingest Tool.
因為此 class 可在網路上找到 Source Code, 所以就能瞭解此程式到 App Store 抓 Report 的做法.
此程式的關鍵就在於 Apple 有放出一個 URL (https://reportingitc.apple.com/autoingestion.tft) 讓需要的人可透過簡單的 HTTP POST 來取得一個 .gz 檔.
取得此 .gz 檔後, 可再自行解壓縮以得到一個 .txt 的 CSV 資料檔, 最後再將此 CSV 格式檔匯入資料庫中.
首先, 先知道要對此 URL 傳送的參數, 此參數說明一樣可在參考文件 3.2 節 [Parameters Definitions] 中找到.
以下簡略地整理參考文件中的參數說明並列表:
參數名 | 範例 | 說明 |
USERNAME | xxxxx | Apple ID |
PASSWORD | ***** | 密碼 |
VNDNUMBER | 8####### | Vendor ID |
TYPEOFREPORT | Sales | 目前僅提供輸入 Sales |
DATETYPE | Daily or Weekly | 日報(14天內)或週報(13 週內) |
REPORTTYPE | Summary or Opt-In | 報表類型 |
REPORTDATE | YYYYMMDD | 欲查詢的日期. 週報請給週日的日期 |
程式部分可以說不用參考到其他特別的 3rd 套件. 當然, 若是想用 HttpClient 包裝傳送的參數, 或是用套件來解 .gz 檔也都可以.
範例如下:
- 程式中需要 import 的 class 如下:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLEncoder; import java.util.zip.GZIPInputStream; import javax.net.ssl.HttpsURLConnection;
- 取得 Report 的主程式:
public static void main(String[] args) { String strAppleID = "xxxxx"; String strPassword = "*****"; String strVenderID = "8#######"; String strTypeOfReport = "Sales"; String strDateType = "Daily"; String strReportType = "Summary"; String strReportDate = "20111030"; HttpsURLConnection objConnection = null; try { // 組合 POST 的參數 StringBuffer sbParameter = new StringBuffer("USERNAME=").append(URLEncoder.encode(strAppleID, "UTF-8")); sbParameter.append("&PASSWORD=").append(URLEncoder.encode(strPassword, "UTF-8")); sbParameter.append("&VNDNUMBER=").append(URLEncoder.encode(strVenderID, "UTF-8")); sbParameter.append("&TYPEOFREPORT=").append(URLEncoder.encode(strTypeOfReport, "UTF-8")); sbParameter.append("&DATETYPE=").append(URLEncoder.encode(strDateType, "UTF-8")); sbParameter.append("&REPORTTYPE=").append(URLEncoder.encode(strReportType, "UTF-8")); sbParameter.append("&REPORTDATE=").append(URLEncoder.encode(strReportDate, "UTF-8")); // 建立連線與設定 Request objConnection = (HttpsURLConnection)(new URL("https://reportingitc.apple.com/autoingestion.tft?").openConnection()); objConnection.setRequestMethod("POST"); objConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); objConnection.setDoOutput(true); // do POST OutputStreamWriter oswWriter = new OutputStreamWriter(objConnection.getOutputStream()); oswWriter.write(sbParameter.toString()); oswWriter.flush(); oswWriter.close(); if (objConnection.getHeaderField("ERRORMSG") != null) { // 如果有錯誤訊息產生, 輸出錯誤訊息 System.out.println(objConnection.getHeaderField("ERRORMSG")); } else if (objConnection.getHeaderField("filename") != null) { // 如果有回傳檔案名稱, 進行檔案處理 getFile(objConnection); } } catch (Exception ex) { ex.printStackTrace(System.out); } finally { // 回收 Connection if (objConnection != null) { objConnection.disconnect(); objConnection = null; } } }
- 在 Step2 中, 我將處理檔案的部分另外寫一個 getFile() 的函式以方便處理. 參考如下:
private static void getFile(HttpsURLConnection objConnection) throws IOException { String strFileName = objConnection.getHeaderField("filename"); // 設定 .gz 檔案的輸出位置 String strGzFileName = "d:\\" + strFileName; int i = 0; BufferedInputStream bisInput = new BufferedInputStream(objConnection.getInputStream()); BufferedOutputStream bosOutput = new BufferedOutputStream(new FileOutputStream(strGzFileName)); byte[] arrayOfByte = new byte[1024]; while ((i = bisInput.read(arrayOfByte)) != -1) { bosOutput.write(arrayOfByte, 0, i); } bisInput.close(); bosOutput.close(); // 設定 解壓後的 .txt 檔案的輸出位置 String strCVSFileName = "d:\\" + strFileName.substring(0, strFileName.length() - 3); GZIPInputStream inGZip = new GZIPInputStream(new FileInputStream(strGzFileName)); FileOutputStream outTxt = new FileOutputStream(strCVSFileName); while ((i = inGZip.read(arrayOfByte)) != -1) { outTxt.write(arrayOfByte, 0, i); } inGZip.close(); outTxt.close(); }
- 若執行無誤, 應該會產生兩個檔案, 一個是下載回來的 .gz 檔, 一個是解壓縮後的 .txt 檔.
- 當 Apple ID 或 password 輸入錯誤時: Error :Your Apple ID or password was entered incorrectly.
- 當 Vender ID 輸入錯誤時: Please enter a valid vendor number.
- 當 REPORTTYPE 輸入錯誤時(包含無 Opt-In 但卻指定 Opt-In): Auto ingestion is not available for this selection.
- 當設定 DATETYPE 為 Weekly, 但日期卻指定錯誤或超過有效期: Weekly reports are available only for past 13 weeks, please enter a weekend date within past 13 weeks.
- 當設定 DATETYPE 為 Daily, 但日期卻指定錯誤或超過有效期: Daily reports are available only for past 14 days, please enter a date within past 14 days.
沒有留言:
張貼留言