Alexander Lucas ทีม Google Analytics API – สิงหาคม 2010
เกริ่นนำ
บทความนี้แสดงวิธีนำข้อมูลจากคำค้นหาไปยัง API การส่งออกข้อมูลของ Google Analytics และแสดงผลลัพธ์เป็นรูปแบบ CSV ยอดนิยม นี่เป็นงานหนึ่งที่คนทั่วไปทำมากที่สุดโดยใช้ข้อมูล Analytics ที่ดึงมาจาก API การส่งออกข้อมูล ดังนั้นการทำให้กระบวนการนี้เป็นไปโดยอัตโนมัติจึงเป็นวิธีง่ายๆ ที่จะช่วยประหยัดเวลาได้มากเป็นประจำ นอกจากนี้ เมื่อคุณมีโค้ดสำหรับพิมพ์เอกสาร CSV จากคำค้นหา คุณก็จะผสานรวมโค้ดนี้ไว้ในโปรเจ็กต์ขนาดใหญ่ได้ เช่น โปรแกรมสร้างรายงานอัตโนมัติ เครื่องมือส่งอีเมล และฟังก์ชัน "ส่งออก" สำหรับแดชบอร์ดที่กำหนดเองที่คุณเขียนไว้
ก่อนเริ่มต้น
คุณจะได้รับประโยชน์สูงสุดจากบทความนี้หากมีสิ่งต่อไปนี้
- ความรู้ในการใช้งาน Java
- ความรู้เกี่ยวกับ Google Analytics รวมถึงความเข้าใจเกี่ยวกับ มิติข้อมูลและเมตริก
- สิทธิ์เข้าถึงบัญชี Google Analytics ที่ใช้งานอยู่ด้วยข้อมูลจริง
- ความคุ้นเคยกับคู่มือเริ่มต้นใช้งาน Java สำหรับ API การส่งออกข้อมูล บทความนี้จะถือว่าคุณทราบข้อมูลทั้งหมดในคู่มือนี้แล้ว
- สำเนาซอร์สโค้ดแบบสมบูรณ์ภายในเครื่อง ซึ่งคุณสามารถดาวน์โหลดได้ที่ AnalyticsCvsPrinter.java คุณสามารถดูตัวอย่างแอปพลิเคชันที่ใช้โค้ดนี้ได้ที่ AnalyticsCsvDemo.java
ภาพรวมของโปรแกรม
โค้ดที่พูดถึงในบทความนี้มีประโยชน์ดังนี้
- เปิดใช้การเลือกระหว่างรันไทม์ว่าจะพิมพ์รหัสไปยังคอนโซลหรือสตรีมไฟล์
- เมื่อใช้ออบเจ็กต์
DataFeed
เป็นพารามิเตอร์ ให้พิมพ์ข้อมูลออกมาในรูปแบบ CSV:- พิมพ์ส่วนหัวของแถว
- พิมพ์แถวข้อมูล โดย
DataEntry
แต่ละรายการประกอบกันเป็น 1 แถวในเอาต์พุตที่ได้ - เรียกใช้แต่ละค่าผ่านวิธีการตรวจสอบความถูกต้องของไฟล์ CSV ที่ปลอดภัย
- เขียนเมธอด "Sanitizer" ที่ทำให้อินพุตทั้งหมดเป็น CSV ที่ปลอดภัย
- มีคลาส Java ที่สามารถใช้คำค้นหา API การส่งออกข้อมูลใดๆ และเปลี่ยนเป็นไฟล์ CSV ได้
อนุญาตให้ใช้สตรีมเอาต์พุตที่กำหนดค่าได้
สิ่งแรกที่ต้องทำคือตั้งค่าสตรีมเอาต์พุตที่กำหนดค่าได้สำหรับชั้นเรียนของคุณเพื่อพิมพ์ วิธีนี้จะทำให้โค้ดที่ใช้คลาสเลือกได้ว่าเอาต์พุตควรจะเป็นมาตรฐานหรือไปยังไฟล์โดยตรง คุณแค่ต้องตั้งค่าเมธอด getter/setter สำหรับออบเจ็กต์ PrintStream
เป้าหมายนี้จะเป็นเป้าหมายของการพิมพ์
ทั้งหมดที่ชั้นเรียนทำ
private PrintStream printStream = System.out; public PrintStream getPrintStream() { return printStream; } public void setPrintStream(PrintStream printStream) { this.printStream = printStream; }
การตั้งค่าเอาต์พุตเป็นไฟล์ก็เป็นเรื่องง่ายมากเช่นกัน ผู้ใช้จะใช้เพียงชื่อไฟล์เท่านั้น
เพื่อสร้างออบเจ็กต์ PrintStream
สำหรับไฟล์นั้น
FileOutputStream fstream = new FileOutputStream(filename); PrintStream stream = new PrintStream(fstream); csvprinter.setPrintStream(stream);
ปรับปรุงตามข้อมูล
แถวแรกของไฟล์ CSV คือแถวของชื่อคอลัมน์ แต่ละคอลัมน์จะแสดงมิติข้อมูลหรือเมตริกจากฟีดข้อมูล ดังนั้นในการพิมพ์แถวแรกนี้ ให้ทำดังนี้
- รับรายการแรกจากฟีด
- ทำซ้ำผ่านรายการมิติข้อมูลโดยใช้เมธอด
getDimensions
ของรายการนั้นๆ - พิมพ์ชื่อของแต่ละมิติข้อมูลโดยใช้เมธอด
Dimension.getName()
แล้วตามด้วยคอมมา - ทำสิ่งเดียวกันกับเมตริกโดยใช้เมธอด
getMetrics()
พิมพ์คอมมายกเว้นเมตริกสุดท้าย
นี่คือการใช้งานวิธีพิมพ์ส่วนหัวของแถว โปรดทราบว่าโค้ดนี้จะไม่แสดงสตริงที่แสดงถึงแถวที่สมบูรณ์ โดยจะพิมพ์ไปยังสตรีมเอาต์พุตขณะประมวลผลค่า
public void printRowHeaders(DataFeed feed) { if(feed.getEntries().size() == 0) { return; } DataEntry firstEntry = feed.getEntries().get(0); Iterator<Dimension> dimensions = firstEntry.getDimensions().iterator(); while (dimensions.hasNext()) { printStream.print(sanitizeForCsv(dimensions.next().getName())); printStream.print(","); } Iterator<Metric> metrics = firstEntry.getMetrics().iterator(); while (metrics.hasNext()) { printStream.print(sanitizeForCsv(metrics.next().getName())); if (metrics.hasNext()) { printStream.print(","); } } printStream.println(); }
การพิมพ์ "เนื้อหา" ของไฟล์ CSV (ทุกอย่างที่อยู่ใต้ชื่อคอลัมน์) จะคล้ายกันมาก โดยมีความแตกต่างที่สำคัญเพียง 2 อย่าง อย่างแรก ไม่ใช่แค่โฆษณาแรกที่ได้รับการประเมิน โค้ดจะต้องวนซ้ำรายการทั้งหมด
ในออบเจ็กต์ฟีด ขั้นตอนที่ 2 ให้ใช้ getValue()
แทนเมธอด getName()
เพื่อดึงค่าที่จะล้างและสั่งพิมพ์
public void printBody(DataFeed feed) { if(feed.getEntries().size() == 0) { return; } for (DataEntry entry : feed.getEntries()) { printEntry(entry); } } public void printEntry(DataEntry entry) { Iterator<Dimension> dimensions = entry.getDimensions().iterator(); while (dimensions.hasNext()) { printStream.print(sanitizeForCsv(dimensions.next().getValue())); printStream.print(","); } Iterator<Metric> metrics = entry.getMetrics().iterator(); while (metrics.hasNext()) { printStream.print(sanitizeForCsv(metrics.next().getValue())); if (metrics.hasNext()) { printStream.print(","); } } printStream.println(); }
โค้ดนี้จะแยกฟีดออกเป็นรายการย่อย และป้อนเป็นค่าที่จะพิมพ์เพื่อส่งออก แต่เราจะทำให้ค่าเหล่านั้นเหมาะกับ CSV ได้อย่างไร จะเกิดอะไรขึ้นหากค่าในไฟล์ "ค่าที่คั่นด้วยเครื่องหมายจุลภาค" มีคอมมา ค่าเหล่านั้นต้องปราศจากสิ่งกีดขวาง
วิธีทำความสะอาดข้อมูลเพื่อความเข้ากันได้กับ CSV
CSV เป็นรูปแบบที่ไม่ซับซ้อน ไฟล์ CSV มีตารางข้อมูลและ แต่ละบรรทัดคือแถวในตารางนั้น ค่าในแถวนั้นจะถูกคั่นด้วยเครื่องหมายคอมมา บรรทัดใหม่หมายถึงแถวข้อมูลใหม่
น่าเสียดายที่รูปแบบที่ตรงไปตรงมานี้ทำให้การประมวลผลข้อมูลที่ไม่ดี เป็นเรื่องง่าย จะเกิดอะไรขึ้นหากค่ามีคอมมา จะเกิดอะไรขึ้นหากค่าใดค่าหนึ่ง ของคุณมีตัวแบ่งบรรทัด ควรจะมีช่องว่างระหว่าง เครื่องหมายคอมมาและค่าเป็นอย่างไร คุณสามารถพิจารณาสถานการณ์ทั้งหมดนี้ได้โดยใช้กฎง่ายๆ ไม่กี่ข้อ
- หากสตริงมีอักขระเครื่องหมายคำพูดคู่ ให้หลีกด้วยอักขระเครื่องหมายคำพูดคู่ที่ 2
- หากมีคอมมาในสตริง ให้รวมสตริงทั้งสตริงไว้ในเครื่องหมายคำพูดคู่ (เว้นแต่คุณจะมีอยู่แล้ว)
- หากมีการแบ่งบรรทัดในสตริง ให้ใส่สตริงทั้งสตริงไว้ในเครื่องหมายคำพูดคู่ (เว้นแต่คุณจะมีอยู่แล้ว)
- หากสตริงเริ่มต้นหรือลงท้ายด้วยช่องว่างทุกประเภท ให้ใส่สตริงทั้งสตริงในเครื่องหมายคำพูดคู่ (เว้นแต่คุณจะมีอยู่แล้ว)
อาจเป็นเรื่องยากเล็กน้อยที่จะเห็นภาพว่าค่าควรมีลักษณะอย่างไรในจุดนี้ ดังนั้นเราจะยกตัวอย่างให้คุณดู อย่าลืมว่าแต่ละตัวอย่างแสดงถึงค่าเดียว และจะ Escape ดังนั้น เพื่อความชัดเจน การเว้นวรรค จะแสดงเป็นอักขระ _
ก่อน | หลัง |
---|---|
ไม่มีการเปลี่ยนแปลง | ไม่มีการเปลี่ยนแปลง |
สุ่ม " เครื่องหมายคำพูดคู่ | สุ่ม "" เครื่องหมายคำพูดคู่ |
คอมมา,คั่นด้วยคอมมา | "คั่นด้วยจุลภาค" |
2 บรรทัด |
"2 บรรทัด" |
วรรคที่นำหน้าและเครื่องหมายคอมมา | "_leading Space และคอมมา" |
"เครื่องหมายคำพูดนำหน้า, คอมมา | """เครื่องหมายอัญประกาศนำหน้า คอมมา" |
_space, คอมมา บรรทัดที่ 2 และเครื่องหมายอัญประกาศคู่" |
"_space, คอมมา บรรทัดที่ 2 และเครื่องหมายคำพูดคู่""" |
วิธีที่ง่ายที่สุดในการจัดการกับสภาวะเหล่านี้ทั้งหมดคือการเขียนวิธีการทำความสะอาด ข้อมูลที่น่าสงสัยจะเข้ามา และมีค่า CSV ที่ดีและสะอาดตา ต่อไปนี้เป็นตัวอย่างการใช้งานที่ดีสำหรับวิธีการดังกล่าว
private String sanitizeForCsv(String cellData) { StringBuilder resultBuilder = new StringBuilder(cellData); // Look for doublequotes, escape as necessary. int lastIndex = 0; while (resultBuilder.indexOf("\"", lastIndex) >= 0) { int quoteIndex = resultBuilder.indexOf("\"", lastIndex); resultBuilder.replace(quoteIndex, quoteIndex + 1, "\"\""); lastIndex = quoteIndex + 2; } char firstChar = cellData.charAt(0); char lastChar = cellData.charAt(cellData.length() - 1); if (cellData.contains(",") || // Check for commas cellData.contains("\n") || // Check for line breaks Character.isWhitespace(firstChar) || // Check for leading whitespace. Character.isWhitespace(lastChar)) { // Check for trailing whitespace resultBuilder.insert(0, "\"").append("\""); // Wrap in doublequotes. } return resultBuilder.toString(); }
วิธีการนี้จะเริ่มต้นด้วยการตรวจสอบเครื่องหมายคำพูดคู่ที่มีอยู่ ควรใช้วิธีนี้ก่อนการตรวจสอบอื่นๆ ทั้งหมด เนื่องจากจะเป็นการตัดสตริงด้วยเครื่องหมายคําพูดคู่ และอาจรบกวนการตัดสินความแตกต่างระหว่างเครื่องหมายคําพูดคู่ที่เป็นส่วนหนึ่งของค่ากับเครื่องหมายคําพูดคู่ที่เพิ่มโดยวิธีการนี้ก่อนหน้านี้ กรณีเหล่านี้หลุดรอดได้ง่าย แต่ต้องเพิ่มเป็น 2 เท่า ทุก " จะกลายเป็น "" และทุกๆ "" จะกลายเป็น """" ไปเรื่อยๆ
เมื่อมีคุณสมบัติตรงตามเงื่อนไขแล้ว ก็จะตรวจสอบเงื่อนไขอื่นๆ ทั้งหมดได้ (ช่องว่าง คอมมา และการขึ้นบรรทัดใหม่) ทั้งหมด หากมีค่าใดค่าหนึ่งอยู่ ให้ใส่ค่าในเครื่องหมายคำพูดคู่
โปรดทราบว่าข้อมูลข้างต้นใช้ออบเจ็กต์ StringBuilder
แต่ไม่ได้จัดการสตริงดิบโดยตรง เนื่องจาก StringBuilder
จะช่วยให้คุณจัดการสตริงได้อย่างอิสระโดยไม่ต้องสร้างสำเนาชั่วคราวในหน่วยความจำ เนื่องจากสตริงใน Java จะเปลี่ยนแปลงไม่ได้ การปรับเปลี่ยนเล็กๆ น้อยๆ
ทุกครั้งจะสร้างสตริงขึ้นใหม่ เมื่อเก็บข้อมูลในสเปรดชีต
ข้อมูลก็เพิ่มขึ้นอย่างรวดเร็ว
จำนวนแถว | x ค่าต่อแถว | x การเปลี่ยนแปลงค่า | = สตริงใหม่ทั้งหมดที่สร้างขึ้น |
---|---|---|---|
10,000 | 10 | 3 | 300,000 |
ฉันต้องทำอะไรต่อไป
ตอนนี้คุณได้รับค้อนทองคำแล้ว การตามล่าตะปูคงจะดีกว่าเดิม ไอเดียบางส่วนที่จะช่วยคุณเริ่มต้นมีดังนี้
- โปรดดูตัวอย่างซอร์สโค้ดของแอปพลิเคชันซึ่งใช้คลาสนี้เพื่อพิมพ์ไฟล์ CSV โดยอิงตามตัวอย่างการค้นหา โดยใช้ชื่อไฟล์เอาต์พุตเป็นพารามิเตอร์บรรทัดคำสั่ง และพิมพ์ออกมาเป็นมาตรฐานโดยค่าเริ่มต้น ใช้เป็นจุดเริ่มต้น สร้าง สิ่งที่เจ๋งๆ!
- CSV เป็นเพียงหนึ่งในรูปแบบต่างๆ ที่ได้รับความนิยม ปรับคลาสเพื่อเอาต์พุตเป็นรูปแบบอื่น เช่น TSV, YAML, JSON หรือ XML
- เขียนแอปพลิเคชันที่สร้างไฟล์ CSV และส่งไปทางไปรษณีย์เมื่อทำเสร็จ การรายงานรายเดือนแบบอัตโนมัติที่แสนง่ายดาย
- เขียนแอปพลิเคชันที่ช่วยให้คุณป้อนคำค้นหาได้แบบอินเทอร์แอกทีฟ เพื่ออินเทอร์เฟซที่มีประสิทธิภาพสำหรับการเจาะลึกข้อมูลภายใน