jobs-referer-parser 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE-2.0.txt +202 -0
- data/README.md +98 -0
- data/Rakefile +10 -0
- data/data/referers.json +4090 -0
- data/data/referers.yml +3621 -0
- data/lib/.DS_Store +0 -0
- data/lib/referer-parser/errors.rb +29 -0
- data/lib/referer-parser/parser.rb +215 -0
- data/lib/referer-parser/version.rb +19 -0
- data/lib/referer-parser.rb +21 -0
- data/referer-parser.gemspec +38 -0
- data/spec/fixtures/internal.json +9 -0
- data/spec/fixtures/invalid.json +1 -0
- data/spec/fixtures/invalid.yml +2 -0
- data/spec/fixtures/referer-tests.json +234 -0
- data/spec/parser_spec.rb +181 -0
- data/spec/spec_helper.rb +35 -0
- metadata +103 -0
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
module RefererParser
|
17
|
+
|
18
|
+
class RefererParserError < StandardError
|
19
|
+
attr_reader :original
|
20
|
+
def initialize(msg, original=nil);
|
21
|
+
super(msg);
|
22
|
+
@original = original;
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class UnsupportedFormatError < RefererParserError; end
|
27
|
+
class InvalidUriError < RefererParserError; end
|
28
|
+
class CorruptReferersError < RefererParserError; end
|
29
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# Copyright (c) 2014 Inside Systems, Inc All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Kelley Reynolds (mailto:kelley@insidesystems.net)
|
13
|
+
# Copyright:: Copyright (c) 2014 Inside Systems Inc
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
require 'uri'
|
17
|
+
require 'cgi'
|
18
|
+
|
19
|
+
module RefererParser
|
20
|
+
class Parser
|
21
|
+
DefaultFile = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'referers.json'))
|
22
|
+
|
23
|
+
# Create a new parser from one or more filenames/uris, defaults to ../data/referers.json
|
24
|
+
def initialize(uris=DefaultFile)
|
25
|
+
@domain_index ||= {}
|
26
|
+
@name_hash ||= {}
|
27
|
+
|
28
|
+
update(uris)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Update the referer database with one or more uris
|
32
|
+
def update(uris)
|
33
|
+
[uris].flatten.each do |uri|
|
34
|
+
deserialize_referer_data(read_referer_data(uri), File.extname(uri).downcase)
|
35
|
+
end
|
36
|
+
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
# Clean out the database
|
41
|
+
def clear!
|
42
|
+
@domain_index, @name_hash = {}, {}
|
43
|
+
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
# Add a referer to the database with medium, name, domain or array of domains, and a parameter or array of parameters
|
48
|
+
# If called manually and a domain is added to an existing entry with a path, you may need to call optimize_index! afterwards.
|
49
|
+
def add_referer(medium, name, domains, parameters=nil)
|
50
|
+
# The same name can be used with multiple mediums so we make a key here
|
51
|
+
name_key = "#{name}-#{medium}"
|
52
|
+
|
53
|
+
# Update the name has with the parameter and medium data
|
54
|
+
@name_hash[name_key] = {:source => name, :medium => medium, :parameters => [parameters].flatten }
|
55
|
+
|
56
|
+
# Update the domain to name index
|
57
|
+
[domains].flatten.each do |domain_url|
|
58
|
+
domain, *path = domain_url.split('/')
|
59
|
+
if domain =~ /\Awww\.(.*)\z/i
|
60
|
+
domain = $1
|
61
|
+
end
|
62
|
+
|
63
|
+
domain.downcase!
|
64
|
+
|
65
|
+
@domain_index[domain] ||= []
|
66
|
+
if !path.empty?
|
67
|
+
@domain_index[domain] << ['/' + path.join('/'), name_key]
|
68
|
+
else
|
69
|
+
@domain_index[domain] << ['/', name_key]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Prune duplicate entries and sort with the most specific path first if there is more than one entry
|
75
|
+
# In this case, sorting by the longest string works fine
|
76
|
+
def optimize_index!
|
77
|
+
@domain_index.each do |key, val|
|
78
|
+
# Sort each path/name_key pair by the longest path
|
79
|
+
@domain_index[key].sort! { |a, b|
|
80
|
+
b[0].size <=> a[0].size
|
81
|
+
}.uniq!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Given a string or URI, return a hash of data
|
86
|
+
def parse(obj)
|
87
|
+
url = obj.is_a?(URI) ? obj : URI.parse(obj.to_s)
|
88
|
+
|
89
|
+
if !['http', 'https'].include?(url.scheme)
|
90
|
+
raise InvalidUriError.new("Only HTTP and HTTPS schemes are supported -- #{url.scheme}")
|
91
|
+
end
|
92
|
+
|
93
|
+
data = { :known => false, :uri => url.to_s }
|
94
|
+
|
95
|
+
domain, name_key = domain_and_name_key_for(url)
|
96
|
+
if domain and name_key
|
97
|
+
referer_data = @name_hash[name_key]
|
98
|
+
data[:known] = true
|
99
|
+
data[:source] = referer_data[:source]
|
100
|
+
data[:medium] = referer_data[:medium]
|
101
|
+
data[:domain] = domain
|
102
|
+
|
103
|
+
# Parse parameters if the referer uses them
|
104
|
+
if url.query and referer_data[:parameters]
|
105
|
+
query_params = CGI.parse(url.query)
|
106
|
+
referer_data[:parameters].each do |param|
|
107
|
+
# If there is a matching parameter, get the first non-blank value
|
108
|
+
if !(values = query_params[param]).empty?
|
109
|
+
data[:term] = values.select { |v| v.strip != "" }.first
|
110
|
+
break if data[:term]
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
data
|
117
|
+
rescue URI::InvalidURIError
|
118
|
+
raise InvalidUriError.new("Unable to parse URI, not a URI? -- #{obj.inspect}", $!)
|
119
|
+
end
|
120
|
+
|
121
|
+
protected
|
122
|
+
|
123
|
+
# Determine the correct name_key for this host and path
|
124
|
+
def domain_and_name_key_for(uri)
|
125
|
+
# Create a proc that will return immediately
|
126
|
+
check = Proc.new do |domain|
|
127
|
+
domain.downcase!
|
128
|
+
if paths = @domain_index[domain]
|
129
|
+
paths.each do |path, name_key|
|
130
|
+
return [domain, name_key] if uri.path.include?(path)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# First check hosts with and without the www prefix with the path
|
136
|
+
if uri.host =~ /\Awww\.(.+)\z/i
|
137
|
+
check.call $1
|
138
|
+
else
|
139
|
+
check.call uri.host
|
140
|
+
end
|
141
|
+
|
142
|
+
# Remove subdomains until only three are left (probably good enough)
|
143
|
+
host_arr = uri.host.split(".")
|
144
|
+
while host_arr.size > 2 do
|
145
|
+
host_arr.shift
|
146
|
+
check.call host_arr.join(".")
|
147
|
+
end
|
148
|
+
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def deserialize_referer_data(data, ext)
|
153
|
+
# Parse the loaded data with the correct parser
|
154
|
+
deserialized_data = if ['.yml', '.yaml'].include?(ext)
|
155
|
+
deserialize_yaml(data)
|
156
|
+
elsif ext == '.json'
|
157
|
+
deserialize_json(data)
|
158
|
+
else
|
159
|
+
raise UnsupportedFormatError.new("Only yaml and json file formats are currently supported -- #{@msg}")
|
160
|
+
end
|
161
|
+
|
162
|
+
begin
|
163
|
+
parse_referer_data deserialized_data
|
164
|
+
rescue
|
165
|
+
raise CorruptReferersError.new("Unable to parse data file -- #{$!.class} #{$!.to_s}", $!)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def deserialize_yaml(data)
|
170
|
+
require 'yaml'
|
171
|
+
YAML.load(data)
|
172
|
+
rescue Exception => e
|
173
|
+
raise CorruptReferersError.new("Unable to YAML file -- #{e.to_s}", e)
|
174
|
+
end
|
175
|
+
|
176
|
+
def deserialize_json(data)
|
177
|
+
require 'json'
|
178
|
+
JSON.parse(data)
|
179
|
+
rescue JSON::ParserError
|
180
|
+
raise CorruptReferersError.new("Unable to JSON file -- #{$!.to_s}", $!)
|
181
|
+
end
|
182
|
+
|
183
|
+
def read_referer_data(uri)
|
184
|
+
# Attempt to read the data from the network if application, or the file on the local system
|
185
|
+
if uri =~ /\A(?:ht|f)tps?:\/\//
|
186
|
+
require 'open-uri'
|
187
|
+
begin
|
188
|
+
open(uri).read
|
189
|
+
rescue OpenURI::HTTPError
|
190
|
+
raise InvalidUriError.new("Cannot load referer data from URI #{uri} -- #{$!.to_s}", $!)
|
191
|
+
end
|
192
|
+
else
|
193
|
+
File.read(uri)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Create an index that maps domains/paths to their name/medium and a hash that contains their metadata
|
198
|
+
# The index strips leading www in order to keep the index smaller
|
199
|
+
# Format of the domain_index:
|
200
|
+
# { domain => [[path1, name_key], [path2, name_key], ... ] }
|
201
|
+
# Format of the name_hash:
|
202
|
+
# { name_key => {:source, :medium, :parameters} }
|
203
|
+
def parse_referer_data(data)
|
204
|
+
data.each do |medium, name_hash|
|
205
|
+
name_hash.each do |name, name_data|
|
206
|
+
add_referer(medium, name, name_data['domains'], name_data['parameters'])
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
optimize_index!
|
211
|
+
rescue
|
212
|
+
raise CorruptReferersError.new("Unable to parse referer data", $!)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Original Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
module RefererParser
|
17
|
+
NAME = "jobs-referer-parser"
|
18
|
+
VERSION = "0.0.1"
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
require "referer-parser/version"
|
17
|
+
require "referer-parser/errors"
|
18
|
+
require "referer-parser/parser"
|
19
|
+
|
20
|
+
module RefererParser
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Snowplow Analytics Ltd. All rights reserved.
|
2
|
+
#
|
3
|
+
# This program is licensed to you under the Apache License Version 2.0,
|
4
|
+
# and you may not use this file except in compliance with the Apache License Version 2.0.
|
5
|
+
# You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing,
|
8
|
+
# software distributed under the Apache License Version 2.0 is distributed on an
|
9
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
11
|
+
|
12
|
+
# Author:: Yali Sassoon (mailto:support@snowplowanalytics.com)
|
13
|
+
# Copyright:: Copyright (c) 2012-2013 Snowplow Analytics Ltd
|
14
|
+
# License:: Apache License Version 2.0
|
15
|
+
|
16
|
+
# -*- encoding: utf-8 -*-
|
17
|
+
lib = File.expand_path('../lib', __FILE__)
|
18
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
19
|
+
require 'referer-parser/version'
|
20
|
+
|
21
|
+
Gem::Specification.new do |gem|
|
22
|
+
gem.authors = ["Yali Sassoon", "Martin Loy", "Alex Dean", "Kelley Reynolds", "Shiv Bharthur"]
|
23
|
+
gem.email = ["shiv@recroup.com"]
|
24
|
+
gem.description = %q{Library for extracting marketing attribution data from referer URLs}
|
25
|
+
gem.summary = %q{Library for extracting marketing attribution data (e.g. search terms) from referer (sic) URLs. This is used by Recroup (http://github.com/bharthur/jobs-referer-parser). Originally developed by Snowplow (http://github.com/snowplow/snowplow).}
|
26
|
+
gem.homepage = "http://github.com/bharthur/jobs-referer-parser"
|
27
|
+
|
28
|
+
gem.files = `git ls-files`.split($/)
|
29
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
30
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
31
|
+
gem.name = RefererParser::NAME
|
32
|
+
gem.version = RefererParser::VERSION
|
33
|
+
gem.platform = Gem::Platform::RUBY
|
34
|
+
gem.require_paths = ["lib"]
|
35
|
+
|
36
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
37
|
+
gem.add_development_dependency "rake", ">= 0.9.2"
|
38
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This has the right extension but is unparsable gibberish to json:{}}}}
|
@@ -0,0 +1,234 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"spec": "Google Images search",
|
4
|
+
"uri": "http://www.google.fr/imgres?q=Ogham+the+celtic+oracle&hl=fr&safe=off&client=firefox-a&hs=ZDu&sa=X&rls=org.mozilla:fr-FR:unofficial&tbm=isch&prmd=imvnsa&tbnid=HUVaj-o88ZRdYM:&imgrefurl=http://www.psychicbazaar.com/oracles/101-ogham-the-celtic-oracle-set.html&docid=DY5_pPFMliYUQM&imgurl=http://mdm.pbzstatic.com/oracles/ogham-the-celtic-oracle-set/montage.png&w=734&h=250&ei=GPdWUIePCOqK0AWp3oCQBA&zoom=1&iact=hc&vpx=129&vpy=276&dur=827&hovh=131&hovw=385&tx=204&ty=71&sig=104115776612919232039&page=1&tbnh=69&tbnw=202&start=0&ndsp=26&ved=1t:429,r:13,s:0,i:114&biw=1272&bih=826",
|
5
|
+
"medium": "search",
|
6
|
+
"source": "Google Images",
|
7
|
+
"term": "Ogham the celtic oracle",
|
8
|
+
"known": true
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"spec": "Yahoo! Images search",
|
12
|
+
"uri": "http://it.images.search.yahoo.com/images/view;_ylt=A0PDodgQmGBQpn4AWQgdDQx.;_ylu=X3oDMTBlMTQ4cGxyBHNlYwNzcgRzbGsDaW1n?back=http%3A%2F%2Fit.images.search.yahoo.com%2Fsearch%2Fimages%3Fp%3DEarth%2BMagic%2BOracle%2BCards%26fr%3Dmcafee%26fr2%3Dpiv-web%26tab%3Dorganic%26ri%3D5&w=1064&h=1551&imgurl=mdm.pbzstatic.com%2Foracles%2Fearth-magic-oracle-cards%2Fcard-1.png&rurl=http%3A%2F%2Fwww.psychicbazaar.com%2Foracles%2F143-earth-magic-oracle-cards.html&size=2.8+KB&name=Earth+Magic+Oracle+Cards+-+Psychic+Bazaar&p=Earth+Magic+Oracle+Cards&oid=f0a5ad5c4211efe1c07515f56cf5a78e&fr2=piv-web&fr=mcafee&tt=Earth%2BMagic%2BOracle%2BCards%2B-%2BPsychic%2BBazaar&b=0&ni=90&no=5&ts=&tab=organic&sigr=126n355ib&sigb=13hbudmkc&sigi=11ta8f0gd&.crumb=IZBOU1c0UHU",
|
13
|
+
"medium": "search",
|
14
|
+
"source": "Yahoo! Images",
|
15
|
+
"term": "Earth Magic Oracle Cards",
|
16
|
+
"known": true
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"spec": "Powered by Google",
|
20
|
+
"uri": "http://isearch.avg.com/pages/images.aspx?q=tarot+card+change&sap=dsp&lang=en&mid=209215200c4147d1a9d6d1565005540b-b0d4f81a8999f5981f04537c5ec8468fd5234593&cid=%7B50F9298B-C111-4C7E-9740-363BF0015949%7D&v=12.1.0.21&ds=AVG&d=7%2F23%2F2012+10%3A31%3A08+PM&pr=fr&sba=06oENya4ZG1YS6vOLJwpLiFdjG91ICt2YE59W2p5ENc2c4w8KvJb5xbvjkj3ceMjnyTSpZq-e6pj7GQUylIQtuK4psJU60wZuI-8PbjX-OqtdX3eIcxbMoxg3qnIasP0ww2fuID1B-p2qJln8vBHxWztkpxeixjZPSppHnrb9fEcx62a9DOR0pZ-V-Kjhd-85bIL0QG5qi1OuA4M1eOP4i_NzJQVRXPQDmXb-CpIcruc2h5FE92Tc8QMUtNiTEWBbX-QiCoXlgbHLpJo5Jlq-zcOisOHNWU2RSHYJnK7IUe_SH6iQ.%2CYT0zO2s9MTA7aD1mNjZmZDBjMjVmZDAxMGU4&snd=hdr&tc=test1",
|
21
|
+
"medium": "search",
|
22
|
+
"source": "Google",
|
23
|
+
"term": "tarot card change",
|
24
|
+
"known": true
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"spec": "Google search #1",
|
28
|
+
"uri": "http://www.google.com/search",
|
29
|
+
"medium": "search",
|
30
|
+
"source": "Google",
|
31
|
+
"term": null,
|
32
|
+
"known": true
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"spec": "Google search #2",
|
36
|
+
"uri": "http://www.google.com/search?q=gateway+oracle+cards+denise+linn&hl=en&client=safari",
|
37
|
+
"medium": "search",
|
38
|
+
"source": "Google",
|
39
|
+
"term": "gateway oracle cards denise linn",
|
40
|
+
"known": true
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"spec": "Yahoo! search",
|
44
|
+
"uri": "http://es.search.yahoo.com/search;_ylt=A7x9QbwbZXxQ9EMAPCKT.Qt.?p=BIEDERMEIER+FORTUNE+TELLING+CARDS&ei=utf-8&type=685749&fr=chr-greentree_gc&xargs=0&pstart=1&b=11",
|
45
|
+
"medium": "search",
|
46
|
+
"source": "Yahoo!",
|
47
|
+
"term": "BIEDERMEIER FORTUNE TELLING CARDS",
|
48
|
+
"known": true
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"spec": "PriceRunner search",
|
52
|
+
"uri": "http://www.pricerunner.co.uk/search?displayNoHitsMessage=1&q=wild+wisdom+of+the+faery+oracle",
|
53
|
+
"medium": "search",
|
54
|
+
"source": "PriceRunner",
|
55
|
+
"term": "wild wisdom of the faery oracle",
|
56
|
+
"known": true
|
57
|
+
},
|
58
|
+
{
|
59
|
+
"spec": "Bing Images search",
|
60
|
+
"uri": "http://www.bing.com/images/search?q=psychic+oracle+cards&view=detail&id=D268EDDEA8D3BF20AF887E62AF41E8518FE96F08",
|
61
|
+
"medium": "search",
|
62
|
+
"source": "Bing Images",
|
63
|
+
"term": "psychic oracle cards",
|
64
|
+
"known": true
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"spec": "IXquick search",
|
68
|
+
"uri": "https://s3-us3.ixquick.com/do/search",
|
69
|
+
"medium": "search",
|
70
|
+
"source": "IXquick",
|
71
|
+
"term": null,
|
72
|
+
"known": true
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"spec": "AOL search",
|
76
|
+
"uri": "http://aolsearch.aol.co.uk/aol/search?s_chn=hp&enabled_terms=&s_it=aoluk-homePage50&q=pendulums",
|
77
|
+
"medium": "search",
|
78
|
+
"source": "AOL",
|
79
|
+
"term": "pendulums",
|
80
|
+
"known": true
|
81
|
+
},
|
82
|
+
{
|
83
|
+
"spec": "AOL search.com",
|
84
|
+
"uri": "http://www.aolsearch.com/search?s_pt=hp&s_gl=NL&query=voorbeeld+cv+competenties&invocationType=tb50hpcnnbie7-nl-nl",
|
85
|
+
"medium": "search",
|
86
|
+
"source": "AOL",
|
87
|
+
"term": "voorbeeld cv competenties",
|
88
|
+
"known": true
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"spec": "Ask search",
|
92
|
+
"uri": "http://uk.search-results.com/web?qsrc=1&o=1921&l=dis&q=pendulums&dm=ctry&atb=sysid%3D406%3Aappid%3D113%3Auid%3D8f40f651e7b608b5%3Auc%3D1346336505%3Aqu%3Dpendulums%3Asrc%3Dcrt%3Ao%3D1921&locale=en_GB",
|
93
|
+
"medium": "search",
|
94
|
+
"source": "Ask",
|
95
|
+
"term": "pendulums",
|
96
|
+
"known": true
|
97
|
+
},
|
98
|
+
{
|
99
|
+
"spec": "Mail.ru search",
|
100
|
+
"uri": "http://go.mail.ru/search?q=Gothic%20Tarot%20Cards&where=any&num=10&rch=e&sf=20",
|
101
|
+
"medium": "search",
|
102
|
+
"source": "Mail.ru",
|
103
|
+
"term": "Gothic Tarot Cards",
|
104
|
+
"known": true
|
105
|
+
},
|
106
|
+
{
|
107
|
+
"spec": "Yandex search",
|
108
|
+
"uri": "http://images.yandex.ru/yandsearch?text=Blue%20Angel%20Oracle%20Blue%20Angel%20Oracle&noreask=1&pos=16&rpt=simage&lr=45&img_url=http%3A%2F%2Fmdm.pbzstatic.com%2Foracles%2Fblue-angel-oracle%2Fbox-small.png",
|
109
|
+
"medium": "search",
|
110
|
+
"source": "Yandex Images",
|
111
|
+
"term": "Blue Angel Oracle Blue Angel Oracle",
|
112
|
+
"known": true
|
113
|
+
},
|
114
|
+
{
|
115
|
+
"spec": "Ask toolbar search",
|
116
|
+
"uri": "http://search.tb.ask.com/search/GGmain.jhtml?cb=AYY&pg=GGmain&p2=%5EAYY%5Exdm071%5EYYA%5Eid&n=77fdaa55&qid=c2678d9147654034bb8b16daa7bfb48c&ss=sub&st=hp&ptb=F9FC6C22-EAE6-4D1E-8126-A70119B6E02F&si=flvrunner&tpr=hst&searchfor=CARA+MEMASAK+CUMI+CUMI&ots=1219016089614",
|
117
|
+
"medium": "search",
|
118
|
+
"source": "Ask Toolbar",
|
119
|
+
"term": "CARA MEMASAK CUMI CUMI",
|
120
|
+
"known": true
|
121
|
+
},
|
122
|
+
{
|
123
|
+
"spec": "Ask toolbar search #2",
|
124
|
+
"uri": "http://search.tb.ask.com/search/GGmain.jhtml?&st=hp&p2=%5EZU%5Exdm458%5EYYA%5Eus&n=77fda1bd&ptb=F0B68CA5-4791-4376-BFCC-5F0100329FB6&si=CMKg9-nX07oCFSjZQgodcikACQ&tpr=hpsbsug&searchfor=test",
|
125
|
+
"medium": "search",
|
126
|
+
"source": "Ask Toolbar",
|
127
|
+
"term": "test",
|
128
|
+
"known": true
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"spec": "Voila search",
|
132
|
+
"uri": "http://search.ke.voila.fr/?module=voila&bhv=web_fr&kw=test",
|
133
|
+
"medium": "search",
|
134
|
+
"source": "Voila",
|
135
|
+
"term": "test",
|
136
|
+
"known": true
|
137
|
+
},
|
138
|
+
{
|
139
|
+
"spec": "Dale search",
|
140
|
+
"uri": "http://www.dalesearch.com/?q=+lego.nl+%2Fclub&s=web&as=0&rlz=0&babsrc=HP_ss",
|
141
|
+
"medium": "search",
|
142
|
+
"source": "Dalesearch",
|
143
|
+
"term": " lego.nl /club",
|
144
|
+
"known": true
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"spec": "Twitter redirect",
|
148
|
+
"uri": "http://t.co/chrgFZDb",
|
149
|
+
"medium": "social",
|
150
|
+
"source": "Twitter",
|
151
|
+
"term": null,
|
152
|
+
"known": true
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"spec": "Facebook social",
|
156
|
+
"uri": "http://www.facebook.com/l.php?u=http%3A%2F%2Fwww.psychicbazaar.com&h=yAQHZtXxS&s=1",
|
157
|
+
"medium": "social",
|
158
|
+
"source": "Facebook",
|
159
|
+
"term": null,
|
160
|
+
"known": true
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"spec": "Facebook mobile",
|
164
|
+
"uri": "http://m.facebook.com/l.php?u=http%3A%2F%2Fwww.psychicbazaar.com%2Fblog%2F2012%2F09%2Fpsychic-bazaar-reviews-tarot-foundations-31-days-to-read-tarot-with-confidence%2F&h=kAQGXKbf9&s=1",
|
165
|
+
"medium": "social",
|
166
|
+
"source": "Facebook",
|
167
|
+
"term": null,
|
168
|
+
"known": true
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"spec": "Odnoklassniki",
|
172
|
+
"uri": "http://www.odnoklassniki.ru/dk?cmd=logExternal&st._aid=Conversations_Openlink&st.name=externalLinkRedirect&st.link=http%3A%2F%2Fwww.psychicbazaar.com%2Foracles%2F187-blue-angel-oracle.html",
|
173
|
+
"medium": "social",
|
174
|
+
"source": "Odnoklassniki",
|
175
|
+
"term": null,
|
176
|
+
"known": true
|
177
|
+
},
|
178
|
+
{
|
179
|
+
"spec": "Tumblr social #1",
|
180
|
+
"uri": "http://www.tumblr.com/dashboard",
|
181
|
+
"medium": "social",
|
182
|
+
"source": "Tumblr",
|
183
|
+
"term": null,
|
184
|
+
"known": true
|
185
|
+
},
|
186
|
+
{
|
187
|
+
"spec": "Tumblr w subdomain",
|
188
|
+
"uri": "http://psychicbazaar.tumblr.com/",
|
189
|
+
"medium": "social",
|
190
|
+
"source": "Tumblr",
|
191
|
+
"term": null,
|
192
|
+
"known": true
|
193
|
+
},
|
194
|
+
{
|
195
|
+
"spec": "Yahoo! Mail",
|
196
|
+
"uri": "http://36ohk6dgmcd1n-c.c.yom.mail.yahoo.net/om/api/1.0/openmail.app.invoke/36ohk6dgmcd1n/11/1.0.35/us/en-US/view.html/0",
|
197
|
+
"medium": "email",
|
198
|
+
"source": "Yahoo! Mail",
|
199
|
+
"term": null,
|
200
|
+
"known": true
|
201
|
+
},
|
202
|
+
{
|
203
|
+
"spec": "Outlook.com mail",
|
204
|
+
"uri": "http://co106w.col106.mail.live.com/default.aspx?rru=inbox",
|
205
|
+
"medium": "email",
|
206
|
+
"source": "Outlook.com",
|
207
|
+
"term": null,
|
208
|
+
"known": true
|
209
|
+
},
|
210
|
+
{
|
211
|
+
"spec": "Orange Webmail",
|
212
|
+
"uri": "http://webmail1m.orange.fr/webmail/fr_FR/read.html?FOLDER=SF_INBOX&IDMSG=8594&check=&SORTBY=31",
|
213
|
+
"medium": "email",
|
214
|
+
"source": "Orange Webmail",
|
215
|
+
"term": null,
|
216
|
+
"known": true
|
217
|
+
},
|
218
|
+
{
|
219
|
+
"spec": "Internal HTTP",
|
220
|
+
"uri": "http://www.snowplowanalytics.com/about/team",
|
221
|
+
"medium": "internal",
|
222
|
+
"source": "SnowPlow",
|
223
|
+
"term": null,
|
224
|
+
"known": true
|
225
|
+
},
|
226
|
+
{
|
227
|
+
"spec": "Internal HTTPS",
|
228
|
+
"uri": "https://www.snowplowanalytics.com/account/profile",
|
229
|
+
"medium": "internal",
|
230
|
+
"source": "SnowPlow",
|
231
|
+
"term": null,
|
232
|
+
"known": true
|
233
|
+
}
|
234
|
+
]
|