نمایش اطلاعات Google Analytics در Asp.net

سه شنبه 5 آبان 1394

توسط Google Analyticsو با کمک Data Export API provided می توانید به آمار بازدید کنندگان سایتتان دسترسی داشته باشید .در این مقاله نحوه نمایش آمار بازدید کنندگان در asp.net را بررسی می کنیم .

نمایش اطلاعات Google Analytics در Asp.net

اگر اکانت Google Analytics داشته باشید می توانید با کمک Data Export API provided به بازدید کنندگان سایتتان دسترسی داشته باشید و اطلاعات مربوط به تعداد بازدید کنندگان و سایر اطلاعات را در هر جا که نیاز بود استفاده کنید.در این مقاله نحوه نمایش آمار بازدید کنندگان در ASP.NET را بررسی می کنیم .

 روش سنتی این است که یک فیلد در دیتابیس مثلا به نام Views تعریف کنیم و به ازای هر بار درخواست صفحه یک واحد به این عدد اضافه کنیم .ولی نمی دانستم چطور تعداد بازدید کنندگان در طی یک ماه یا مثلا 7 روز گذشته را به دست آورم.و دوباره باید کد و دیتا بیس را برای این خواسته تغییر دهم.!!!

این روش معقول نیست . ذخیره سازی اطلاعات بازدید کاربران، در طول زمان حجم بالایی از بانک اطلاعاتی را به خود اختصاص خواهد داد؛ به علاوه کند شدن کوئری‌های مرتبط با آن، به همراه مصرف بالای منابع سیستم را نیز در پی دارد.

بهتر است از روش  Google AnalyticsData Export API استفاده کنم که امکان دسترسی به اکانت Google Analytics را به من می دهد.این روش مزایای دیگری نیزدارد علاوه بر موثق بودن آمار می توان درصد کاربران ار کشورها و شهر های مختلف را به دست آورد، اینکه از چه مرورگری استفاده می کنند، نوع موتور جستجویی که با ان وارد شده اند چیست ، از طریق چه کلمات کلیدی به سایت شما رسیده اند و.......

ابتدا به تعریف یک سری لغت از نظر سرویس آمار گر گوگل یا همان Google Analytics می پردازیم

ابعاد (Dimensions):  یک شی می باشد که می تواند مقادیر مختلفی داشته باشد. مرورگر, خروج از صفحه, 

متریک ها یا معیار ها (Metrics): مقادیر منحصر به فردی از ابعاد هستند که به صورت یک مقدار یا یک نسبت اندازه گیری می شوند.

صفحه های مشاهده شده, صفحات مشاهده شده در هر دوره و میانگین زمان دوره ها نمونه هایی از متریک هایی هستند .

تعداد بازدید از صفحه (Pageviews): به معنی تعداد کل صفحات مشاهده شده می باشد. نمایش مکرر یک صفحه محاسبه می شود.
استفاده از API  سخت نیست و شامل سه مرحله است.

1-ورود به سیستم به وسیله http Post و گرفتن یک مجوز

2-دادن درخواست آمار بازدید کنندگان به وسیله HTTP GET و به دست آوردن یک data feed

3-نمایش فید در سایت

public static string HttpPostRequest(string url, string post)
{
  var encoding = new ASCIIEncoding();
  byte[] data = encoding.GetBytes(post);
  WebRequest request = WebRequest.Create(url);
  request.Method = "POST";
  request.ContentType = "application/x-www-form-urlencoded";
  request.ContentLength = data.Length;
  Stream stream = request.GetRequestStream();
  stream.Write(data, 0, data.Length);
  stream.Close();
  WebResponse response = request.GetResponse();
  String result;
  using (var sr = new StreamReader(response.GetResponseStream()))
  {
    result = sr.ReadToEnd();
    sr.Close();
  }
  return result;
}
public static string HttpGetRequest(string url, string[] headers)
{
  String result;
  WebRequest request = WebRequest.Create(url);
  if (headers.Length > 0)
  {
    foreach (var header in headers)
    {
      request.Headers.Add(header);
    }
  }
  WebResponse response = request.GetResponse();
  using (var sr = new StreamReader(response.GetResponseStream()))
  {
    result = sr.ReadToEnd();
    sr.Close();
  }
  return result;
}

این دو متد حقیقتا متد های پرکاربردی هستند .که من هر دو را در کلاس  HttpRequests تعریف کرده ام.این دو متد از کلاس های WebRequest  و WebResponse  استفاده می کنند.

برای مدیریت ابعاد و متریک( Dimensions and Metrics) یک کلاسی به نام  Dimensions.cs ساخته و کد های زیر را در آن قرار می دهیم.

public enum Dimension
{
  pagePath,
  pageTitle
}

سپس برای متریک که تابع زیر است هم عمل مشابه را انجام میدهیم.

public enum Metric
{
  pageviews
}

Enum نهایی که به آن احتیاج دارم در زیر امده است

public enum SortDirection
{
  Ascending,
  Descending
}

در این مرحله من احتیاج دارم که با یک داده strongly typed کار کنم ولی دیتایی که Google Analytics در اختیار من قرار می دهد به صورت XML است .به منظور اینکه انچه مد نظرم است را بتوانم گزارش گیری کنم پراپرتی Dimensions  دو آیتم را درون خود نگه داری خواهد کرد.در صورتی که پراپرتی متریک یک جفت کلید و مقدار را درون خود نگه خواهد داشت.

بعد از این مراحل نیاز است که دیتا را ایجاد کنیم که خود شامل سه مرحله است

تصدیق

گرفتن  XML document

تبدیل  XML document به اطلاعات

هر سه اینها را به عنوان متد هایی در کلاس GAReporter تعریف خواهیم کرد.متد اول یک authenticated  از گوگل دریافت خواهد کرد.متد دوم اطلاعات را به دست اورده و سومین متد به فرمت دلخواه ما در می اورد.

برای شروع سه پارامتر Const به شکل زیر تعریف کرده ام.

private const string AuthenticationUrl = "https://www.google.com/accounts/ClientLogin";
private const string AuthenticationPost =
  "accountType=GOOGLE&Email=xxx@gmail.com&Passwd=xxx&service=analytics&source=xxx-xxx";
private const string PageViewReportUrl = 
  "https://www.google.com/analytics/feeds/data?ids={0}&dimensions={1}&metrics={2}&start-date={3}&end-date={4}&sort={5}&max-results={6}";

تمام گزارش ها به پارامتر ها مانند صفحه گزارش نیاز ندارند.گزارش های بیشتر به ثابت های بیشتری هم نیاز دارد.

متد Authentication مشابه زیر خواهد بود

private static string Authentication()
{
  string key = null;
  string result = HttpRequests.HttpPostRequest(AuthenticationUrl, AuthenticationPost);
  var tokens = result.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
  foreach (var item in tokens)
  {
    if (item.StartsWith("Auth="))
      key = item;
  }
  return key;
}

همانطور که می بینید این متد از HttpPostRequest helper استفاده می کند.وقتی که قصد دارید لاگین کنید شما پاسخی شامل سه مقدار دریافت می کنید.مقداری که با "Auth=" شروع می شودباید نگه داشته شود.این مقدار وقتی که Report data درخواست می شود  باید به Google پاس داده شود.دومین متد دیتا با فرمت xml را بازمی گرداند

این متد مسئول بازگرداندن دیتایxml از گوگل است.با داشتن کلید authentication  از متد Authenticate() حلقه در بین کالکشنی از Dimensionsو Metricsکه به آن پاس داده می شود به پیمایش می پردازدو همراه پارامتر دیگر یک آدرس Valid به کمک query string می سازد که دیتا را از طریق آن به دست خواهیم آورد.

آخرین متد به نام getXMLData() مسول ساخت XDocument object از getXMLDoc() است.

private static XDocument getXMLData(string account, IEnumerable<Dimension> dimensions, 
		IEnumerable<Metric> metrics, DateTime from, DateTime to, Metric sort, SortDirection direction, int maxrecords)
{
  XDocument doc = null;
  var key = Authentication();
  if (key.Length > 0)
  {
    var dimension = new StringBuilder();
    for (var i = 0; i < dimensions.Count(); i++)
    {
      dimension.Append("ga:" + dimensions.ElementAt(i));
      if (i < dimensions.Count() - 1)
        dimension.Append(",");
    }
    var metric = new StringBuilder();
    for (var i = 0; i < metrics.Count(); i++)
    {
      metric.Append("ga:" + metrics.ElementAt(i));
      if (i < metrics.Count() - 1)
        metric.Append(",");
    }
    var sorter = "ga:" + sort;
    if (direction == SortDirection.Descending)
      sorter = "-" + sorter;
    var fromDate = from.ToString("yyyy-MM-dd");
    var toDate = to.ToString("yyyy-MM-dd");
    var url = string.Format(PageViewReportUrl, "ga:" + account, dimension, metric, fromDate, toDate, sorter, maxrecords);
    var header = new[] { "Authorization: GoogleLogin " + key };
    doc = XDocument.Parse(HttpRequests.HttpGetRequest(url, header));
  }
  return doc;
}

شکل بالا دیتایی که توسط گوگل analytics باز گردانده می شود را نشان میدهد.یک قسمت از این دیتا مشخص شده است.همانطور که می بینید این دیتا شامل المان هایی با پیشوند dxp است.این پیشوند دو نوع است  dxp:dimensionو dxp:metric.کد LINQ to XML در کدهایی که تا به الان نوشته ایم این فایل را به عنوان ورودی می گیرد. xml.Root.Descendants(dns + "entry") یک کالکشنی از نودهای <entry> بازمی گرداند.در هر کدام از نودها ، نود dxp:dimension انتخاب شده است.و یک ویژگی انها به نام name، Dimension  نام گذاری شده است.و ویژگی value آنها با Value در جفت مقادیر Key/value مقدار دهی شده است.

اگر با Enumerations آشنایی داشته باشید حتما می دانید که  ParseEnum<T>()  برای چه فراخوانی شده است.همانطور که در کد زیر می بینید این تابع یک extension method است که من برای پوشش تابع Enum.Parse() از آن استفاده کرده ام.

public static IEnumerable<BaseData> GetBaseData(string account, IEnumerable<Dimension> dimensions, 
		IEnumerable<Metric> metrics, DateTime from, DateTime to, Metric sort, SortDirection direction, int maxrecords)
{
  IEnumerable<BaseData> data = null;
  XDocument xml = getXMLData(account, dimensions, metrics, from, to, sort, direction, maxrecords);
  if (xml != null)
  {
    XNamespace dxp = xml.Root.GetNamespaceOfPrefix("dxp");
    XNamespace dns = xml.Root.GetDefaultNamespace();
    data = xml.Root.Descendants(dns + "entry").Select(element => new BaseData
    {
      Dimensions =
        new List<KeyValuePair<Dimension, string>>(
        element.Elements(dxp + "dimension").Select(
          dimensionElement =>
          new KeyValuePair<Dimension, string>(
            dimensionElement.Attribute("name").Value.Replace("ga:", "")
            .ParseEnum<Dimension>(),
            dimensionElement.Attribute("value").Value))),
      Metrics =
        new List<KeyValuePair<Metric, string>>(
        from metricElement in element.Elements(dxp + "metric")
        select new KeyValuePair<Metric, string>(
          metricElement.Attribute("name").Value.Replace("ga:", "")
            .ParseEnum<Metric>(),
          metricElement.Attribute("value").Value))
    });
  }
  return data;
}

در این مرحله نیاز داریم که یک کلاس بسازیم که اطلاعات مربوط به ویوی صفحه را درون خود نگه دارد.

public class PageViewReportData
{
  public string Url { get; set; }
  public string Title { get; set; }
  public int Views { get; set; }
}

و یک مد برای ساخت آن

public class PageViewReporter
{
  public static IEnumerable<PageViewReportData> GetPageViewReport(string account, DateTime from, DateTime to, int max)
  {
    var dims = new Dimension[] { Dimension.pagePath, Dimension.pageTitle };
    var mets = new Metric[] {Metric.pageviews};
    var sort = Metric.pageviews;
    var order = SortDirection.Descending;
    IEnumerable<BaseData> data = GAReporter.GetBaseData(account, dims, mets, from, to, sort, order, max);
    return data.Select(d => new PageViewReportData
                  {
                    Url = d.Dimensions.First(dim => dim.Key == Dimension.pagePath).Value,
                    Title = d.Dimensions.First(dim => dim.Key == Dimension.pageTitle).Value,
                    Views = Convert.ToInt32(d.Metrics.First(met => met.Key == Metric.pageviews).Value)
                  });
  }
}

شکل زیر اطلاعات مهمی که مربوط به صفحه می باشد را نشان می دهد.

شاید آخرین چیزی که قصد داشته باشید که گوگل برای شما نمایش دهد اطلاعات مربوط به موقعیت یا "Local است توصیه من به استفاده از جاوااسکریپت در این زمینه است.من jQuery که از یک Action به نام GetGoogleData استفاده می کند  ، به کار برده ام

کد مربوط به Action به صورت زیر است

public ActionResult GetGoogleData(int days)
{
  DateTime toDate = DateTime.Now.AddDays(-days);
  DateTime fromDate = DateTime.Now;
  IEnumerable<PageViewReportData>  data = PageViewReporter.GetPageViewReport("xxxxxx", toDate, fromDate, 15);
  return View("VisitorStatsPartial", data);
}

و کد مربوط به jQuery به شکل زیر است

$(document).ready(function() {
  $("#analyticsdata7").html("<img src=\"../../images/loading.gif\" />");
  $.ajax({
    type: "GET",
    contentType: "text/html",
    url: "/Article/GetGoogleData/7",
    success: function(response) {
    $("#analyticsdata7").empty();
    $("#analyticsdata7").html(response);
    }
  });
 });

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید