在第三章 [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 如下:12345678910
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 的主程式:12345678910111213141516171819202122232425262728293031323334353637383940414243444546
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() 的函式以方便處理. 參考如下:12345678910111213141516171819202122232425
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.
沒有留言:
張貼留言