إخراج البيانات من واجهة برمجة التطبيقات لتصدير البيانات إلى تنسيق CSV

ألكسندر لوكاس، فريق Google Analytics API - آب (أغسطس) 2010


المقدمة

توضّح هذه المقالة كيفية أخذ البيانات من أي طلب بحث تم إجراؤه على واجهة برمجة تطبيقات تصدير بيانات "إحصاءات Google" وإخراج النتائج إلى تنسيق CSV الرائج. وهذه إحدى المهام الأكثر شيوعًا التي ينفّذها الأشخاص باستخدام بيانات "إحصاءات Google" المستمدة من واجهة برمجة التطبيقات لتصدير البيانات، لذا يمثّل التشغيل التلقائي للطريقة وسيلة سهلة لتوفير الكثير من الوقت بصفة منتظمة. بالإضافة إلى ذلك، بعد الحصول على بعض الرموز لطباعة مستندات CSV من طلبات البحث، ستتمكّن من دمج ذلك في المشاريع الأكبر حجمًا، مثل أدوات إنشاء التقارير التلقائية، ورسائل البريد، "التصدير&quot، ولوحات البيانات المخصّصة التي كتبتها.

قبل البدء

ستحصل على أقصى استفادة من هذه المقالة إذا كان لديك ما يلي:

  • المعرفة العملية بلغة Java.
  • معرفة عملية بخدمة "إحصاءات Google"، بما في ذلك فهم السمات والمقاييس.
  • الوصول إلى حساب "إحصاءات Google" نشط باستخدام بيانات فعلية
  • اطّلِع على دليل بدء استخدام Java API لتصدير البيانات. تفترض هذه المقالة أنك على دراية بكل المعلومات الواردة في هذا الدليل.
  • نسخة محلية من رمز المصدر الكامل، الذي يمكنك الحصول عليه في AnalyticsCvsPrinter.java. يمكن العثور على نموذج للتطبيق باستخدام هذا الرمز على AnalyticsCsvDemo.java.

نظرة عامّة حول البرنامج

سيعمل الرمز الذي تتناوله هذه المقالة على ما يلي:

  1. يمكنك تفعيل الاختيار في وقت التشغيل، سواء كان الرمز يطبع إلى وحدة التحكّم أو إلى مصدر بيانات.
  2. بالنسبة إلى الكائن DataFeed كمَعلمة، يمكنك طباعة البيانات بتنسيق CSV:
    • طباعة رؤوس الصفوف
    • يمكنك طباعة صفوف البيانات، حيث يشكّل كل DataEntry صفًا واحدًا في الناتج الناتج.
    • يمكنك تشغيل كل قيمة من خلال طريقة التعقيم لإخراج ملف CSV آمن.
  3. اكتب طريقة &عرض الأسعار، أي طريقة جعل كل البيانات آمنة باستخدام ملف CSV.
  4. قدّم لك فئة Java يمكن استخدامها في أي طلب بيانات من واجهة برمجة التطبيقات لتصدير البيانات وتحويله إلى ملف CSV.

الرجوع إلى أعلى الصفحة

السماح بمصادر البيانات القابلة للضبط

أول ما يجب فعله هو إعداد مصدر بيانات قابل للضبط لصفك لالطباعة إليه. وبهذه الطريقة، يمكن لأي رمز يستخدم صفك أن يقرر ما إذا كان يجب تحويل الإخراج إلى ملف عادي أو إلى ملف مباشرةً. ما عليك سوى إعداد طريقة get/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 هو صف أسماء الأعمدة. يُمثّل كل عمود سمة أو مقياسًا من خلاصة البيانات، لذلك من أجل طباعة هذا الصف الأول، يمكنك إجراء ما يلي.

  1. احصُل على الإدخال الأول من الخلاصة.
  2. كرِّر هذه العملية من خلال قائمة السمات باستخدام طريقة getDimensions هذه الإدخال.
  3. اطبع اسم كل سمة باستخدام الطريقة Dimension.getName()، متبوعةً بفاصلة.
  4. كرِّر الإجراء نفسه مع المقاييس باستخدام الطريقة 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 (&)، أي النص الذي يظهر في ملف CSV، (كل ما يظهر أسفل صف أسماء الأعمدة). هناك اختلافان رئيسيان فقط. أولاً، لا يقتصر الأمر على الإدخال الأول الذي يتم تقييمه. يحتاج الرمز إلى تكرار جميع إدخالات عنصر الخلاصة. ثانيًا، استخدِم 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 جدول بيانات، في حين يمثل كل سطر صفًا في هذا الجدول. تكون القيم في هذا الصف مفصولة بفواصل. السطر الجديد يعني صفًا جديدًا من البيانات.

للأسف، إنّ هذا التنسيق البسيط يسهّل عليك التخلص من المحتوى الذي يحتوي على بيانات غير صحيحة. ماذا لو كانت القيمة تحتوي على فاصلة؟ ماذا لو احتوت إحدى القيم على فواصل أسطر؟ ماذا يجب أن يحدث في المسافة بين الفاصلة والقيم؟ يمكن أخذ كل هذه الحالات في الاعتبار باستخدام بعض القواعد البسيطة.

  • إذا كانت السلسلة تحتوي على حرف علامة اقتباس مزدوجة، عليك تجنّبها بحرف اقتباس مزدوج.
  • إذا كانت هناك فاصلة في السلسلة، عليك لف السلسلة بالكامل بين علامتَي اقتباس (ما لم تكن لديك فاصلة).
  • إذا كان هناك فاصل سطر في السلسلة، يمكنك لف السلسلة بالكامل بين علامتَي اقتباس (ما لم تكن لديك فاصلة من قبل).
  • إذا كانت السلسلة تبدأ أو تنتهي بأي نوع من المسافات البيضاء، يجب لف السلسلة بالكامل بين علامتَي اقتباس (ما لم تكن لديك هذه العلامة من قبل).

قد يكون من الصعب إلى حد كبير عرض الشكل الذي يجب أن تظهر به القيم، لذا إليك بعض الأمثلة. تذكّر أنّ كل مثال يمثّل قيمة واحدة ويتمّ تجنّبه بهذه القيمة. وللتوضيح، سيتم عرض المسافات كحرف _.

قبل بعد
بدون تغيير بدون تغيير
علامة اقتباس عشوائية اقتباس عشوائي&&
مفصولة بفواصل &;;فاصلة,مفصّلة&quot
سطران
"سطران
&
_المسافة البادئة وفاصلة "فاصلة بادئة وفاصلة&quot
اقتباس &فاصلة، فاصلة """quot;الاقتباس البادئ, فاصلة&quot
_مسافة، فاصلة
السطر الثاني، وعلامة اقتباس مزدوجة
"_space، وفاصلة
السطر الثاني، وعلامة اقتباس مزدوجة"""

أسهل طريقة للتعامل مع هذه الشروط هي كتابة طريقة للضبط. يتم تقديم بيانات مشكوك فيها، ويتم عرض قيم 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();
}

تبدأ الطريقة بالتحقق من علامات الاقتباس المزدوجة الحالية. يجب إجراء ذلك قبل جميع عمليات التحقق الأخرى، حيث إنها تشتمل على لفّ سلسلة تتضمّن علامات اقتباس مزدوجة، وسيكون من الصعب تحديد الفرق بين علامات الاقتباس المزدوجة التي كانت جزءًا من القيمة وعلامات الاقتباس المزدوجة التي تمت إضافتها سابقًا بهذه الطريقة. يسهُل الهروب منها - ولكن يجب مضاعفةها. تصبح كل " علامة اقتباس ""، وكل ""، وعلامة """"، وما إلى ذلك.

بعد استيفاء هذا الشرط، يمكن التحقّق من جميع الشروط الأخرى (المسافات البيضاء غير الفاصلة أو الفواصل أو فواصل الأسطر). وفي حال توفُّر أيٍّ منها، ما عليك سوى لفّ القيمة بين علامتَي اقتباس.

لاحظ أنّ ما ورد أعلاه يستخدم كائن StringBuilder، ولا يمكن أبدًا التلاعب بسلسلة أساسية. ويعود السبب في ذلك إلى أنّ StringBuilder يسمح لك بمعالجة السلسلة بحرية بدون إنشاء نُسخ مؤقتة في الذاكرة. وبما أن السلاسل في Java غير قابلة للتغيير، فإن كل تعديل بسيط تُنشئه سلسلة جديدة تمامًا. يمكن أن تؤدي هذه التغييرات إلى زيادة سرعة الاشتراك عند تغيير بيانات جدول البيانات.

عدد الصفوف x القيمة لكل صف x التغييرات على القيمة = إجمالي السلاسل الجديدة التي تم إنشاؤها
10,000 10 3 300000

الرجوع إلى أعلى الصفحة

ما الخطوات التالية؟

الآن وبعد أن عرفت مطرقة ذهبية، من الطبيعي أن تصطاد الأظافر. إليك بعض الأفكار لمساعدتك في البدء.

  • يمكنك الاطّلاع على نموذج رمز مصدر التطبيق الذي يستخدم هذه الفئة لطباعة ملف CSV بناءً على نموذج طلب بحث. ويتطلب ذلك اسم ملف للمخرجات كمعلّمة سطر أوامر، كما يطبع معيارًا تلقائيًا. يمكنك استخدامه كنقطة بداية، وإنشاء محتوى رائع.
  • ملف CSV هو أحد التنسيقات الرائجة المتعددة. عدِّل الفئة لإخراجها إلى تنسيق مختلف، مثل TSV أو YAML أو JSON أو XML.
  • اكتب تطبيقًا يُنشئ ملفات CSV ويرسلها عند الانتهاء. إعداد تقارير تلقائية بسهولة
  • يمكنك كتابة تطبيق يسمح لك بإدخال طلبات البحث بشكل تفاعلي، للحصول على واجهة فعّالة لاستكشاف البيانات من الداخل.