<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Startup Monkeys &#187; analytics</title>
	<atom:link href="http://www.startupmonkeys.com/tag/analytics/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.startupmonkeys.com</link>
	<description>Stuff we find or create</description>
	<lastBuildDate>Thu, 02 Sep 2010 15:03:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Ruby Script to Extract Google Analytics Keywords, Landing Page, Medium Entrances to CSV/TSV format</title>
		<link>http://www.startupmonkeys.com/2010/04/ruby-script-to-extract-google-analytics-keywords-landing-page-medium-entrances-to-csvtsv-format/</link>
		<comments>http://www.startupmonkeys.com/2010/04/ruby-script-to-extract-google-analytics-keywords-landing-page-medium-entrances-to-csvtsv-format/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 20:36:49 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[extract]]></category>
		<category><![CDATA[google analytics]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.startupmonkeys.com/?p=26</guid>
		<description><![CDATA[I&#8217;ve had versions of this script hacked together before.  In fact, if you search for &#8220;Google Analytics Data Extractor&#8221; the #1 result is a google groups posting I made in a former life for a C# program I developed: http://groups.google.com/group/analytics-help-misc/browse_thread/thread/d2ad6ddf3d73e511 There&#8217;s now a couple of ruby gems out there for handling the Google Analytics API [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had versions of this script hacked together before.  In fact, if you search for &#8220;Google Analytics Data Extractor&#8221; the #1 result is a google groups posting I made in a former life for a C# program I developed: <a href="http://groups.google.com/group/analytics-help-misc/browse_thread/thread/d2ad6ddf3d73e511">http://groups.google.com/group/analytics-help-misc/browse_thread/thread/d2ad6ddf3d73e511</a></p>
<p>There&#8217;s now a <a href="http://code.google.com/apis/analytics/docs/gdata/gdataLibraries.html">couple of ruby gems out there</a> for handling the <a href="http://code.google.com/apis/analytics/docs/">Google Analytics API</a></p>
<p>One of them I&#8217;ve been doing some light-contributing to, including the pagination support (automatically grab all results in 10,000 result chunks)</p>
<p>I pushed a couple of changes up today at: <a href="http://github.com/er1c/gattica">http://github.com/er1c/gattica</a> that hopefully will get merged into the main trunk soon (<a href="http://github.com/activenetwork/gattica">http://github.com/activenetwork/gattica</a>)</p>
<p>One of the more useful uses of the library is to extract your Organic Search Results Keywords from Google Analytics.  We&#8217;re using this at <a href="http://frugalmechanic.com">Frugal Mechanic</a> to see how people search for <a href="http://frugalmechanic.com/auto-parts">Auto Parts</a>.</p>
<pre class="ruby">require 'rubygems'
require 'gattica'
require 'fastercsv'

ga_profile = "" #Enter your Profile Here
start_date = Date.new(2009, 1, 1)
end_date = Date.new(2009, 12, 31)
file_path = "data" # Directory Needs to exist

puts "Google Username: "
u = gets.chomp
raise "bad username" unless !u.empty?
puts "Google Password: "
system "stty -echo"
pw = gets.chomp
system "stty echo"
raise "bad password" unless !pw.empty?

class ExtractKeywords
  def initialize(email,password)
    @gs = Gattica.new({:email =&gt; email, :password =&gt; password})
  end

  def get_accounts
    results = []
    @gs.accounts.each{|account|
      profile = {}
      profile[:site_title] = account.title
      profile[:profile_id] = account.profile_id ## this is the id required for requests to the API
      profile[:account_name] = account.account_name
      profile[:account_id] = account.account_id
      profile[:web_property_id] = account.web_property_id
      results &lt;&lt; profile     }     return results   end   def connect_profile(profile)     @gs.profile_id = profile[:profile_id]   end   def connect_profile_id(profile_id)     @gs.profile_id = profile_id   end   def get_keywords(start_date = nil, end_date = Date.today)     results = []     csv_data = @gs.get({         :start_date =&gt; (start_date || (end_date - 365)).to_s,
        :end_date =&gt; end_date.to_s,
        :dimensions =&gt; ["medium", "keyword", "landingPagePath"],
        :metrics =&gt; "entrances",
        :sort =&gt; "-entrances",
        :page =&gt; true}).to_csv(:long)

    return FasterCSV.parse(csv_data, :headers =&gt; true)
  end

end

gs = ExtractKeywords.new(u, pw)
gs.connect_profile_id(ga_profile)

(start_date .. end_date).each { |date|
  file = "#{file_path}/medium_keyword_landingpage_visits_#{date.strftime('%Y-%m-%d')}.csv"
  next if File::exists?( file )

  FasterCSV.open(file, "w") do |csv|
    csv &lt;&lt; ["medium", "keyword", "landingPagePath", "entrances"]
    keywords = gs.get_keywords(date, date)
    keywords.each{|row|
      csv &lt;&lt; [row["medium"], row["keyword"], row["landingPagePath"], row["entrances"]]
    }

  end
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmonkeys.com/2010/04/ruby-script-to-extract-google-analytics-keywords-landing-page-medium-entrances-to-csvtsv-format/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails Plugin for Google Website Optimizer for AB Tests &#8211; Dynamic Content Experiments and No Flickering!</title>
		<link>http://www.startupmonkeys.com/2010/01/rails-plugin-for-google-website-optimizer-for-ab-tests-dynamic-content-experiments-and-no-flickering/</link>
		<comments>http://www.startupmonkeys.com/2010/01/rails-plugin-for-google-website-optimizer-for-ab-tests-dynamic-content-experiments-and-no-flickering/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 03:29:23 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[ab testing]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[multivariate]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[website optimizer]]></category>

		<guid isPermaLink="false">http://www.startupmonkeys.com/?p=4</guid>
		<description><![CDATA[Note: If you don&#8217;t care how this plugin works and just want to see/get the code, it&#8217;s available at github: http://github.com/tpunder/gwo There&#8217;s a ton of reasons to reasons to invest in conversion rate increases.  If you&#8217;re spending $1 to acquire 10 visits, and you can get 2 instead of 1 to convert its like putting [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Note:</strong> If you don&#8217;t care how this plugin works and just want to see/get the code, it&#8217;s available at github: <a href="http://github.com/tpunder/gwo">http://github.com/tpunder/gwo</a></em></p>
<p>There&#8217;s a ton of reasons to reasons to invest in conversion rate increases.  If you&#8217;re spending $1 to acquire 10 visits, and you can get 2 instead of 1 to convert its like putting an extra dollar in your pocket.   A couple days ago Rand Fishkin from SEOMoz even said &#8220;<a href="http://www.seomoz.org/blog/8-predictions-for-seo-in-2010">2010 is the Year of Conversion Rate Optimization</a>&#8220;</p>
<p>Google Website Optimizer&#8217;s Homepage will give you a <a href="http://www.google.com/websiteoptimizer" target="_blank">number of reasons to use their product</a> My biggest reasons is its <strong>FREE!</strong></p>
<p>Last March, we met with <a href="http://gwotricks.com">Eric Vasilik</a> with the Google Website Optimizer Team in the Seattle Google Office about some hang-ups we had trying to A/B Test functionality and integrate Google Website Optimizer:</p>
<ol>
<li><strong>Speed.</strong> The out-of-the-box Google Website Optimizer code does something like this:
<ol>
<li>Download/Initialize GWO Code</li>
<li>Identify which experiment/treatment group the user should see</li>
<li>Download each of the content sections that should change and</li>
<li>Use javascript to dynamically update each of the content sections of the page (FLICKER!)</li>
</ol>
</li>
<li><strong>Static Content.</strong> Since you must store the HTML fragments in GWO for the service to return back the appropriate multivariate combination to show to users, the HTML fragments must be static.</li>
<li><strong>Maintenance.</strong> This ties back to our #2 reason, we would have to upload each of the HTML fragments into the GWO tool so they could be tested.  Since we have to code them locally to make sure they function &amp; display correctly anyhow, it effectively means we need to duplicate the code to GWO.</li>
</ol>
<p>The solution?  Leveraging a few very very clever Javascript/HTML tricks this is what we&#8217;re doing for our <a href="http://frugalmechanic.com">Auto Parts Price Comparison</a> site.</p>
<p><strong>Background:</strong></p>
<p>A vanilla GWO Implementation operates similar to:</p>
<p><a href="http://www.startupmonkeys.com/wp-content/uploads/GWO-Basic1.png"><img class="aligncenter size-medium wp-image-12" title="GWO Basic" src="http://www.startupmonkeys.com/wp-content/uploads/GWO-Basic1-300x111.png" alt="" width="300" height="111" /></a></p>
<p>Tricked out solution looks like:</p>
<p><a href="http://www.startupmonkeys.com/wp-content/uploads/GWO-Advanced.png"><img class="aligncenter size-medium wp-image-8" title="GWO Advanced" src="http://www.startupmonkeys.com/wp-content/uploads/GWO-Advanced-300x119.png" alt="" width="300" height="119" /></a></p>
<p>Why is it clever?  Lets walk through each of the scenarios for the GWO Variations.</p>
<p><strong>Scenario 1: No Javascript Support</strong></p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Default content &#8211;&gt;<br />
&lt;script&gt;<br />
var GWO_Section1 = utmx(&#8220;variation_number&#8221;, &#8220;Section1&#8243;);<br />
if (GWO_Section1 != undefined &amp;&amp; GWO_Section1 != 0) document.write(&#8216;&lt;no&#8217; + &#8216;script&gt;&#8217;);<br />
&lt;/script&gt;<br />
</span>Default content &#8211; shown by default&lt;br&gt;<br />
&lt;/noscript&gt;</p>
</blockquote>
<p>Browser ignores everything inside &lt;script&gt; tags and ignores the &lt;/noscript&gt;</p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Variation 1 &#8211;&gt;<br />
&lt;script&gt;<br />
if (GWO_Section1 == 1) document.write(&#8216;&lt;/noscript a=&#8221;&#8216;);<br />
&lt;/script&gt;&lt;!&#8211;&#8221;&gt;<br />
Alternative content 1&lt;br&gt;<br />
&lt;script&gt;document.write(&#8216;&lt;&#8217;+'!&#8217;+'-&#8217;+'-&#8217;)&lt;/script&gt;&#8211;&gt;</span></p>
<p>&lt;!&#8211; Section1 &#8211; Variation 2 &#8211;&gt;<br />
&lt;script&gt;<br />
if (GWO_Section1 == 2) document.write(&#8216;&lt;/noscript a=&#8221;&#8216;);<br />
&lt;/script&gt;&lt;!&#8211;&#8221;&gt;<br />
Alternative content 2&lt;br&gt;<br />
&lt;script&gt;document.write(&#8216;&lt;&#8217;+'!&#8217;+'-&#8217;+'-&#8217;)&lt;/script&gt;&#8211;&gt;</p>
</blockquote>
<p><strong>Scenario 2: Browser Supports Javascript &#8211; Variation == Control/Default Treatment</strong></p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Default content &#8211;&gt;<br />
&lt;script&gt;<br />
var GWO_Section1 = utmx(&#8220;variation_number&#8221;, &#8220;Section1&#8243;);<br />
if (GWO_Section1 != undefined &amp;&amp; GWO_Section1 != 0) document.write(&#8216;&lt;no&#8217; + &#8216;script&gt;&#8217;);<br />
&lt;/script&gt;<br />
Default content &#8211; shown by default&lt;br&gt;<br />
&lt;/noscript&gt;</span></p>
</blockquote>
<p>Browser evaluates GWO_Section == 0 so the document.write(&lt;noscript&gt;) is NOT executed resulting HTML code is:</p>
<blockquote><p>Default content &#8211; shown by default&lt;br&gt;<br />
&lt;/noscript&gt;</p>
</blockquote>
<p>Browser ignores the &lt;/noscript&gt;</p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Variation 1 &#8211;&gt;<br />
&lt;script&gt;<br />
if (GWO_Section1 == 1) document.write(&#8216;&lt;/noscript a=&#8221;&#8216;);<br />
&lt;/script&gt;&lt;!&#8211;&#8221;&gt;<br />
Alternative content 1&lt;br&gt;<br />
&lt;script&gt;document.write(&#8216;&lt;&#8217;+'!&#8217;+'-&#8217;+'-&#8217;)&lt;/script&gt;&#8211;&gt;</span></p>
</blockquote>
<p>Since GWO_Section == 0, the document.write(&#8216;&lt;/noscript is not executed, but however the 2nd &lt;script&gt;document.write IS still executed resulting in</p>
<blockquote><p>&lt;!&#8211;&#8221;&gt;<br />
Alternative content 1&lt;br&gt;<br />
&lt;!&#8211;&lt;/script&gt;&#8211;&gt;</p>
</blockquote>
<p>The HTML comment starts with the first &lt;!&#8211; and keeps going until &#8211;&gt; hits (the browser doesn&#8217;t even try to interpret the DOM inside the HTML comment &#8211; making this the most efficient way to &#8220;throw away&#8221; code from even being parsed by the HTML engine.  The variation 1 never gets displayed.</p>
<p><strong>Scenario 3: Browser Supports Javascript &#8211; Variation == Experiment Treatment</strong></p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Default content &#8211;&gt;<br />
&lt;script&gt;<br />
var GWO_Section1 = utmx(&#8220;variation_number&#8221;, &#8220;Section1&#8243;);<br />
if (GWO_Section1 != undefined &amp;&amp; GWO_Section1 != 0) document.write(&#8216;&lt;no&#8217; + &#8216;script&gt;&#8217;);<br />
&lt;/script&gt;<br />
Default content &#8211; shown by default&lt;br&gt;<br />
&lt;/noscript&gt;</span></p>
</blockquote>
<p>Browser evaluates GWO_Section1 == 1 so it DOES print the &lt;noscript&gt; resulting in:</p>
<blockquote><p>&lt;noscript&gt;<br />
Default content &#8211; show by default&lt;br&gt;<br />
&lt;/noscript&gt;</p>
</blockquote>
<p>Browser starts at the first &lt;noscript&gt; and ignores everything until the ending &lt;/noscript&gt; &#8211; thereby ignoring the control treatment&#8217;s HTML</p>
<blockquote><p><span style="text-decoration: line-through;">&lt;!&#8211; Section1 &#8211; Variation 1 &#8211;&gt;<br />
&lt;script&gt;<br />
if (GWO_Section1 == 1) document.write(&#8216;&lt;/noscript a=&#8221;&#8216;);<br />
&lt;/script&gt;&lt;!&#8211;&#8221;&gt;<br />
Alternative content 1&lt;br&gt;<br />
&lt;script&gt;document.write(&#8216;&lt;&#8217;+'!&#8217;+'-&#8217;+'-&#8217;)&lt;/script&gt;&#8211;&gt;</span></p>
</blockquote>
<p>GWO_Section1 evaluates to == 1 and the document.write prints out resulting in:</p>
<blockquote><p>&lt;/noscript a=&#8221;<br />
&lt;!&#8211;&#8221;&gt;<br />
Alternative content 1&lt;br&gt;<br />
&lt;!&#8211;&lt;/script&gt;&#8211;&gt;</p>
</blockquote>
<p>There&#8217;s two clever things in this one.  The first is the a=&#8221; starts to create an HTML attribute that &#8220;ingests&#8221; the dangling &lt;!&#8211;.  The second, is the &lt;!&#8211;&lt;/script&gt;&#8211;&gt; is a complete HTML comment, so there isn&#8217;t a dangling &lt;/script&gt; tag floating in the HTML.  Poof the Web Browser is now showing the Treatment HTML.</p>
<p>After we met with Eric he posted a link and an explanation for this trick at <a href="http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html" target="_blank">http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html</a></p>
<p>We have a Rails Plugin that encapsulates all of this logic pretty well &#8211; so you don&#8217;t have to worry about all of the javascript hacks:</p>
<p><a href="http://github.com/tpunder/gwo" target="_blank">http://github.com/tpunder/gwo</a></p>
<p>Happy A/B + Multivariate Testing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.startupmonkeys.com/2010/01/rails-plugin-for-google-website-optimizer-for-ab-tests-dynamic-content-experiments-and-no-flickering/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
