google_custom_search_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ rdoc/*
3
+ *.gem
4
+ .bundle
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,2 @@
1
+ = Changelog
2
+
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ google_custom_search_api (0.0.1)
5
+ httparty
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ addressable (2.2.7)
11
+ crack (0.3.1)
12
+ diff-lcs (1.1.3)
13
+ httparty (0.8.1)
14
+ multi_json
15
+ multi_xml
16
+ json (1.6.5)
17
+ multi_json (1.1.0)
18
+ multi_xml (0.4.2)
19
+ rspec (2.9.0)
20
+ rspec-core (~> 2.9.0)
21
+ rspec-expectations (~> 2.9.0)
22
+ rspec-mocks (~> 2.9.0)
23
+ rspec-core (2.9.0)
24
+ rspec-expectations (2.9.0)
25
+ diff-lcs (~> 1.1.3)
26
+ rspec-mocks (2.9.0)
27
+ webmock (1.8.3)
28
+ addressable (>= 2.2.7)
29
+ crack (>= 0.1.7)
30
+
31
+ PLATFORMS
32
+ ruby
33
+
34
+ DEPENDENCIES
35
+ google_custom_search_api!
36
+ json
37
+ rspec
38
+ webmock
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Ben Wiseley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Google Custom Search
2
+
3
+ This project is a Ruby lib for Google's Custom Search ENgine API (http://www.google.com/cse). There seem to be quite a few cse libs out there that don't work so I rolled this up quickly.
4
+
5
+ Questions/comments, etc: wiseleyb@gmail.com
6
+
7
+ ## Install
8
+
9
+ Add to your Gemfile:
10
+
11
+ gem "google_custom_search_api"
12
+
13
+ then
14
+
15
+ bundle install
16
+
17
+ ## Configure
18
+
19
+ You need to configure ```GOOGLE_SEARCH_CX``` and ```GOOGLE_API_KEY``` to ```config/initializers/google_cse_api.rb```:
20
+
21
+ ```
22
+ GOOGLE_API_KEY = "..."
23
+ GOOGLE_SEARCH_CX = "..."
24
+ ```
25
+ You can get your ```GOOGLE_API_KEY``` from https://code.google.com/apis/console/b/0/?pli=1 - There are many choices - Simple API Access is probably what you want. There are more elaborate authorization schemes available for Google services but those aren't currently implemented.
26
+
27
+ You can get your ```GOOGLE_SEARCH_CX``` from http://www.google.com/cse/ Either create a custom engine or follow ```manage your existing search engines``` and go to your cse's Control panel. ```GOOGLE_SEARCH_CX``` == ```Search engine unique ID```
28
+
29
+ ### Searching the web, not just your site, with CSE
30
+
31
+ Google CSE was set up so search specific sites. To search the entire web simply go to http://www.google.com/cse/, find your CSE, go to it's control panel.
32
+
33
+ * in ```Basics``` under ```Search Preferences``` choose ```Search the entire web but emphasize included sites.```
34
+ * in ```Sites``` add ```www.google.com```
35
+
36
+ ## Use
37
+
38
+ To perform a search:
39
+
40
+ ```
41
+ results = GoogleCustomSearchApi.search("poker")
42
+ ```
43
+ Results now contains a raw version and a class'ed version of the data show in ```Sample results``` below.
44
+
45
+ This means you can do:
46
+
47
+ ```
48
+ results["items"].each do |item|
49
+ puts item["title"], item["link"]
50
+ end
51
+ ```
52
+
53
+ or
54
+
55
+ ```
56
+ results.items.each do |item|
57
+ puts item.title, item.link
58
+ end
59
+ ```
60
+
61
+ See [Custom Search](http://code.google.com/apis/customsearch/v1/using_rest.html) documentation for an explanation of all fields available.
62
+
63
+ ### Paging
64
+
65
+ By default CSE returns a maximum of 10 results at a time, you can't get more results without paging. BTW if you want fewer results just pass in the :num => 1-10 option when searching.
66
+
67
+ To do paging we pass in the :start option. Example:
68
+
69
+ ```
70
+ results = GoogleCustomSearchApi.search("poker", :start => 1)
71
+ ```
72
+
73
+ The maximum number of pages CSE allows is 10 - or 100 results in total. To walk through the pages you can use :start => 1, :start => 11, etc. Or you can use the results to find the next value, like so:
74
+
75
+ ```
76
+ start = 1
77
+ begin
78
+ results = GoogleCustomSearchApi.search("poker",:start => start)
79
+ if results.queries.keys.include?("nextPage")
80
+ start = results.queries.nextPage.first.startIndex
81
+ else
82
+ start = nil
83
+ end
84
+ end while start.nil? == false
85
+ ```
86
+
87
+ If you just want all results you can use the method ```search_and_return_all_results(query, opts = {})``` works just like the normal search but iterates through all available results and puts them in an array.
88
+
89
+ ### Encoding issues
90
+
91
+ TODO - this section needs work
92
+
93
+ CSE will return non utf-8 results which can be problematic. I might add in a config value that you can explicitly set encoding. Until then a work around is doing stuff like:
94
+
95
+ ```
96
+ results.items.first.title.force_encoding(Encoding::UTF_8)
97
+ ```
98
+
99
+ More on this here: http://code.google.com/apis/customsearch/docs/ref_encoding.html
100
+
101
+ ## Contributing - Running tests
102
+
103
+ Pull requests welcome.
104
+
105
+ To run tests
106
+ ```
107
+ git clone git@github.com:wiseleyb/google_custom_search_api.git
108
+ cd google_custom_search_api
109
+ bundle install
110
+ bundle exec rspec spec
111
+ ```
112
+
113
+ ## Credits
114
+ * Based largely on the gem https://github.com/alexreisner/google_custom_search
115
+ * Awesome ResponseData class from https://github.com/mikedemers/rbing
116
+ * Work done while working on a project for the company http://reInteractive.net in sunny Sydney. A great ruby shop should you need help with something.
117
+
118
+ ## TODO
119
+ * pretty light on the tests
120
+
121
+ ## Sample results
122
+
123
+ See spec/fixtures/*.json for examples of data returned
124
+
125
+
126
+ Copyright (c) 2012 Ben Wiseley, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
12
+
13
+ require 'rake/rdoctask'
14
+ Rake::RDocTask.new do |rdoc|
15
+ rdoc.rdoc_dir = 'rdoc'
16
+ rdoc.title = "Google Custom Search API #{GoogleCustomSearch::VERSION}"
17
+ rdoc.rdoc_files.include('*.rdoc')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
@@ -0,0 +1,107 @@
1
+ ##
2
+ # Add search functionality (via Google Custom Search). Protocol reference at:
3
+ # http://www.google.com/coop/docs/cse/resultsxml.html
4
+ #
5
+ module GoogleCustomSearchApi
6
+ extend self
7
+
8
+ ##
9
+ # Search the site.
10
+ #
11
+ # opts
12
+ # see list here for valid options http://code.google.com/apis/customsearch/v1/using_rest.html#query-params
13
+ def search(query, opts = {})
14
+ # Get and parse results.
15
+ url = url(query, opts)
16
+ puts url
17
+ return nil unless results = fetch(url)
18
+ results["items"] ||= []
19
+ ResponseData.new(results)
20
+ end
21
+
22
+ def search_and_return_all_results(query, opts = {})
23
+ res = []
24
+ opts[:start] ||= 1
25
+ begin
26
+ results = GoogleCustomSearchApi.search("poker",opts)
27
+ res << results
28
+ if results.queries.keys.include?("nextPage")
29
+ opts[:start] = results.queries.nextPage.first.startIndex
30
+ else
31
+ opts[:start] = nil
32
+ end
33
+ end while opts[:start].nil? == false
34
+ return res
35
+ end
36
+
37
+ # Convenience wrapper for the response Hash.
38
+ # Converts keys to Strings. Crawls through all
39
+ # member data and converts any other Hashes it
40
+ # finds. Provides access to values through
41
+ # method calls, which will convert underscored
42
+ # to camel case.
43
+ #
44
+ # Usage:
45
+ #
46
+ # rd = ResponseData.new("AlphaBeta" => 1, "Results" => {"Gamma" => 2, "delta" => [3, 4]})
47
+ # puts rd.alpha_beta
48
+ # => 1
49
+ # puts rd.alpha_beta.results.gamma
50
+ # => 2
51
+ # puts rd.alpha_beta.results.delta
52
+ # => [3, 4]
53
+ #
54
+ class ResponseData < Hash
55
+ private
56
+ def initialize(data={})
57
+ data.each_pair {|k,v| self[k.to_s] = deep_parse(v) }
58
+ end
59
+ def deep_parse(data)
60
+ case data
61
+ when Hash
62
+ self.class.new(data)
63
+ when Array
64
+ data.map {|v| deep_parse(v) }
65
+ else
66
+ data
67
+ end
68
+ end
69
+ def method_missing(*args)
70
+ name = args[0].to_s
71
+ return self[name] if has_key? name
72
+ camelname = name.split('_').map {|w| "#{w[0,1].upcase}#{w[1..-1]}" }.join("")
73
+ if has_key? camelname
74
+ self[camelname]
75
+ else
76
+ super *args
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ private # -------------------------------------------------------------------
83
+
84
+ ##
85
+ # Build search request URL.
86
+ #
87
+ # see list here for valid options http://code.google.com/apis/customsearch/v1/using_rest.html#query-params
88
+ def url(query, opts = {})
89
+ opts[:q] = query
90
+ opts[:alt] ||= "json"
91
+ uri = Addressable::URI.new
92
+ uri.query_values = opts
93
+ begin
94
+ params.merge!(GOOGLE_SEARCH_PARAMS)
95
+ rescue NameError
96
+ end
97
+ "https://www.googleapis.com/customsearch/v1?key=#{GOOGLE_API_KEY}&cx=#{GOOGLE_SEARCH_CX}&#{uri.query}"
98
+ end
99
+
100
+ ##
101
+ # Query Google, and make sure it responds.
102
+ #
103
+ def fetch(url)
104
+ return HTTParty.get(url)
105
+ end
106
+
107
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module GoogleCustomSearchApi
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,31 @@
1
+ {
2
+ "kind": "customsearch#search",
3
+ "url": {
4
+ "type": "application/json",
5
+ "template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&cref={cref?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
6
+ },
7
+ "queries": {
8
+ "request": [
9
+ {
10
+ "title": "Google Custom Search - asdfojasoidfjao sdfjaosdfj aosdijfoaisdjfoasjdofijas dofijweo fwoef jwoeifjw",
11
+ "totalResults": "0",
12
+ "searchTerms": "asdfojasoidfjao sdfjaosdfj aosdijfoaisdjfoasjdofijas dofijweo fwoef jwoeifjw",
13
+ "count": 10,
14
+ "inputEncoding": "utf8",
15
+ "outputEncoding": "utf8",
16
+ "safe": "off",
17
+ "cx": "002432975944642411257:ztx9u0hzbcw"
18
+ }
19
+ ]
20
+ },
21
+ "searchInformation": {
22
+ "searchTime": 0.121274,
23
+ "formattedSearchTime": "0.12",
24
+ "totalResults": "0",
25
+ "formattedTotalResults": "0"
26
+ },
27
+ "spelling": {
28
+ "correctedQuery": "asdf ojasoidfjao sdfj sdfj aosdijfoaisdjfoasjdofijas dofijweo fwoef jwoeifjw",
29
+ "htmlCorrectedQuery": "\u003cb\u003e\u003ci\u003easdf ojasoidfjao\u003c/i\u003e\u003c/b\u003e \u003cb\u003e\u003ci\u003esdfj sdfj\u003c/i\u003e\u003c/b\u003e aosdijfoaisdjfoasjdofijas dofijweo fwoef jwoeifjw"
30
+ }
31
+ }
@@ -0,0 +1,290 @@
1
+ {
2
+ "kind": "customsearch#search",
3
+ "url": {
4
+ "type": "application/json",
5
+ "template": "https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&cref={cref?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
6
+ },
7
+ "queries": {
8
+ "nextPage": [
9
+ {
10
+ "title": "Google Custom Search - poker",
11
+ "totalResults": "40500000",
12
+ "searchTerms": "poker",
13
+ "count": 10,
14
+ "startIndex": 11,
15
+ "inputEncoding": "utf8",
16
+ "outputEncoding": "utf8",
17
+ "safe": "off",
18
+ "cx": "002432975944642411257:ztx9u0hzbcw"
19
+ }
20
+ ],
21
+ "request": [
22
+ {
23
+ "title": "Google Custom Search - poker",
24
+ "totalResults": "40500000",
25
+ "searchTerms": "poker",
26
+ "count": 10,
27
+ "startIndex": 1,
28
+ "inputEncoding": "utf8",
29
+ "outputEncoding": "utf8",
30
+ "safe": "off",
31
+ "cx": "002432975944642411257:ztx9u0hzbcw"
32
+ }
33
+ ]
34
+ },
35
+ "context": {
36
+ "title": "ICMS Dev"
37
+ },
38
+ "searchInformation": {
39
+ "searchTime": 0.193868,
40
+ "formattedSearchTime": "0.19",
41
+ "totalResults": "40500000",
42
+ "formattedTotalResults": "40,500,000"
43
+ },
44
+ "items": [
45
+ {
46
+ "kind": "customsearch#result",
47
+ "title": "Official World Series of Poker Online",
48
+ "htmlTitle": "Official World Series of \u003cb\u003ePoker\u003c/b\u003e Online",
49
+ "link": "http://www.wsop.com/",
50
+ "displayLink": "www.wsop.com",
51
+ "snippet": "Official website of the World Series of Poker Tournament. Featuring poker tournament coverage of events, schedules and news. Play online poker games like ...",
52
+ "htmlSnippet": "Official website of the World Series of \u003cb\u003ePoker\u003c/b\u003e Tournament. Featuring \u003cb\u003epoker\u003c/b\u003e \u003cbr\u003e tournament coverage of events, schedules and news. Play online \u003cb\u003epoker\u003c/b\u003e games \u003cbr\u003e like \u003cb\u003e...\u003c/b\u003e",
53
+ "cacheId": "T7q1CfbZcPwJ",
54
+ "formattedUrl": "www.wsop.com/",
55
+ "htmlFormattedUrl": "www.wsop.com/",
56
+ "pagemap": {
57
+ "cse_image": [
58
+ {
59
+ "src": "http://www.wsop.com/images/hm/download_image.jpg"
60
+ }
61
+ ],
62
+ "cse_thumbnail": [
63
+ {
64
+ "width": "185",
65
+ "height": "113",
66
+ "src": "https://encrypted-tbn1.google.com/images?q=tbn:ANd9GcQzUUbsQCEJ9huedBRALkpQPN6QBBwgwIFT2_cEA9hkkJYBehSvRygrQw"
67
+ }
68
+ ]
69
+ }
70
+ },
71
+ {
72
+ "kind": "customsearch#result",
73
+ "title": "Poker - Wikipedia, the free encyclopedia",
74
+ "htmlTitle": "\u003cb\u003ePoker\u003c/b\u003e - Wikipedia, the free encyclopedia",
75
+ "link": "http://en.wikipedia.org/wiki/Poker",
76
+ "displayLink": "en.wikipedia.org",
77
+ "snippet": "Poker is a family of card games involving betting and individualistic play whereby the winner is determined by the ranks and combinations of their cards, some of ...",
78
+ "htmlSnippet": "\u003cb\u003ePoker\u003c/b\u003e is a family of card games involving betting and individualistic play whereby \u003cbr\u003e the winner is determined by the ranks and combinations of their cards, some of \u003cb\u003e...\u003c/b\u003e",
79
+ "cacheId": "M0JijEuvEdkJ",
80
+ "formattedUrl": "en.wikipedia.org/wiki/Poker",
81
+ "htmlFormattedUrl": "en.wikipedia.org/wiki/\u003cb\u003ePoker\u003c/b\u003e",
82
+ "pagemap": {
83
+ "cse_image": [
84
+ {
85
+ "src": "http://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Holdem.jpg/300px-Holdem.jpg"
86
+ }
87
+ ],
88
+ "cse_thumbnail": [
89
+ {
90
+ "width": "240",
91
+ "height": "171",
92
+ "src": "https://encrypted-tbn2.google.com/images?q=tbn:ANd9GcStTlDjK3fS8LXRP2QSifQ1Q5dg0dwpak2LR9aGzPTavzts2b62_Q6t91k"
93
+ }
94
+ ]
95
+ }
96
+ },
97
+ {
98
+ "kind": "customsearch#result",
99
+ "title": "Online Poker - Play Online at Full Tilt Poker Room",
100
+ "htmlTitle": "Online \u003cb\u003ePoker\u003c/b\u003e - Play Online at Full Tilt \u003cb\u003ePoker\u003c/b\u003e Room",
101
+ "link": "http://www.fulltiltpoker.com/",
102
+ "displayLink": "www.fulltiltpoker.com",
103
+ "snippet": "Online Poker at the Fastest Growing Online Poker Room. Full Tilt Poker offers the best in online poker: world famous pros, a huge bonus, real or play money.",
104
+ "htmlSnippet": "Online \u003cb\u003ePoker\u003c/b\u003e at the Fastest Growing Online \u003cb\u003ePoker\u003c/b\u003e Room. Full Tilt \u003cb\u003ePoker\u003c/b\u003e offers the \u003cbr\u003e best in online \u003cb\u003epoker\u003c/b\u003e: world famous pros, a huge bonus, real or play money.",
105
+ "cacheId": "-0lVMr2LbU0J",
106
+ "formattedUrl": "www.fulltiltpoker.com/",
107
+ "htmlFormattedUrl": "www.fulltilt\u003cb\u003epoker\u003c/b\u003e.com/",
108
+ "pagemap": {
109
+ "cse_image": [
110
+ {
111
+ "src": "http://w.fulltiltcdn.net/images/global/content/home/video-player-still.png"
112
+ }
113
+ ],
114
+ "cse_thumbnail": [
115
+ {
116
+ "width": "206",
117
+ "height": "183",
118
+ "src": "https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcQNl-iv7LDBN5OsGiWYzyH1ezgTvB2gwEIHhPLqJ0Tkd2OmQiywk0P7fyQ"
119
+ }
120
+ ],
121
+ "metatags": [
122
+ {
123
+ "uid": "10",
124
+ "nav_title": "Online Poker"
125
+ }
126
+ ]
127
+ }
128
+ },
129
+ {
130
+ "kind": "customsearch#result",
131
+ "title": "Poker.com - Online Poker Games, Free Tournaments, Rules & News",
132
+ "htmlTitle": "\u003cb\u003ePoker\u003c/b\u003e.com - Online \u003cb\u003ePoker\u003c/b\u003e Games, Free Tournaments, Rules &amp; News",
133
+ "link": "http://www.poker.com/",
134
+ "displayLink": "www.poker.com",
135
+ "snippet": "The world's #1 free poker information website, with poker game rules, news, tournaments and reviews of all the best online poker rooms.",
136
+ "htmlSnippet": "The world&#39;s #1 free \u003cb\u003epoker\u003c/b\u003e information website, with \u003cb\u003epoker\u003c/b\u003e game rules, news, \u003cbr\u003e tournaments and reviews of all the best online \u003cb\u003epoker\u003c/b\u003e rooms.",
137
+ "cacheId": "IlkL1Yc3_F8J",
138
+ "formattedUrl": "www.poker.com/",
139
+ "htmlFormattedUrl": "www.\u003cb\u003epoker\u003c/b\u003e.com/",
140
+ "pagemap": {
141
+ "cse_image": [
142
+ {
143
+ "src": "http://www.poker.com/pokernews/wp-content/uploads/2011/03/poker.jpg"
144
+ }
145
+ ],
146
+ "cse_thumbnail": [
147
+ {
148
+ "width": "115",
149
+ "height": "115",
150
+ "src": "https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcRQrcdYcF0OGtXZ2SCv7CP55Z7O_is7guk6l-wEw5s85I-Z-UcBwJ3V9g"
151
+ }
152
+ ]
153
+ }
154
+ },
155
+ {
156
+ "kind": "customsearch#result",
157
+ "title": "Online Poker Sites Toplists & Bonus Offers, Poker Reviews and News",
158
+ "htmlTitle": "Online \u003cb\u003ePoker\u003c/b\u003e Sites Toplists &amp; Bonus Offers, \u003cb\u003ePoker\u003c/b\u003e Reviews and News",
159
+ "link": "http://www.pokerlistings.com/",
160
+ "displayLink": "www.pokerlistings.com",
161
+ "snippet": "5 hours ago ... PokerListings is the world's largest online poker guide with the best bonus offers guaranteed and exclusive free tournaments for new players.",
162
+ "htmlSnippet": "5 hours ago \u003cb\u003e...\u003c/b\u003e PokerListings is the world&#39;s largest online \u003cb\u003epoker\u003c/b\u003e guide with the best bonus offers \u003cbr\u003e guaranteed and exclusive free tournaments for new players.",
163
+ "cacheId": "dq71R1WBRMUJ",
164
+ "formattedUrl": "www.pokerlistings.com/",
165
+ "htmlFormattedUrl": "www.\u003cb\u003epoker\u003c/b\u003elistings.com/",
166
+ "pagemap": {
167
+ "cse_image": [
168
+ {
169
+ "src": "http://edge1.pokerlistings.com/assets/Uploads/EN-584x323-AffBanner-2.jpg"
170
+ }
171
+ ],
172
+ "cse_thumbnail": [
173
+ {
174
+ "width": "302",
175
+ "height": "167",
176
+ "src": "https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcTXMaQ0pVWAUfo2V7ydD3a2sHYiFEPjA4zSEMJAKbC3GQ2Y2PzRAtttp1B3"
177
+ }
178
+ ]
179
+ }
180
+ },
181
+ {
182
+ "kind": "customsearch#result",
183
+ "title": "Governor of Poker - Hot Games at Miniclip.com - Play Free Online ...",
184
+ "htmlTitle": "Governor of \u003cb\u003ePoker\u003c/b\u003e - Hot Games at Miniclip.com - Play Free Online \u003cb\u003e...\u003c/b\u003e",
185
+ "link": "http://www.miniclip.com/games/governor-of-poker/en/",
186
+ "displayLink": "www.miniclip.com",
187
+ "snippet": "Win all your games in your hometown and become the Governor of Poker!",
188
+ "htmlSnippet": "Win all your games in your hometown and become the Governor of \u003cb\u003ePoker\u003c/b\u003e!"
189
+ },
190
+ {
191
+ "kind": "customsearch#result",
192
+ "title": "Online Poker | Play at Pacific poker online and get $8 FREE",
193
+ "htmlTitle": "Online \u003cb\u003ePoker\u003c/b\u003e | Play at Pacific \u003cb\u003epoker\u003c/b\u003e online and get $8 FREE",
194
+ "link": "http://www.pacificpoker.com/",
195
+ "displayLink": "www.pacificpoker.com",
196
+ "snippet": "Play online poker at Pacific Poker and get $8 FREE AND $400 bonus to play poker online at 888 poker - the largest and most trusted online poker room.",
197
+ "htmlSnippet": "Play online \u003cb\u003epoker\u003c/b\u003e at Pacific \u003cb\u003ePoker\u003c/b\u003e and get $8 FREE AND $400 bonus to play \u003cbr\u003e \u003cb\u003epoker\u003c/b\u003e online at 888 \u003cb\u003epoker\u003c/b\u003e - the largest and most trusted online \u003cb\u003epoker\u003c/b\u003e room.",
198
+ "cacheId": "sYy5C08rRZYJ",
199
+ "formattedUrl": "www.pacificpoker.com/",
200
+ "htmlFormattedUrl": "www.pacific\u003cb\u003epoker\u003c/b\u003e.com/",
201
+ "pagemap": {
202
+ "cse_image": [
203
+ {
204
+ "src": "http://images.888.com/newpoker/lang/en_new/PCP-main_december-400.jpg"
205
+ }
206
+ ],
207
+ "cse_thumbnail": [
208
+ {
209
+ "width": "339",
210
+ "height": "148",
211
+ "src": "https://encrypted-tbn3.google.com/images?q=tbn:ANd9GcQ0kVbE22EZPQE2iGUuqRFBEzh2odvIS7LfKBDNKBKkxOCoj4TAeMgEZ7c"
212
+ }
213
+ ]
214
+ }
215
+ },
216
+ {
217
+ "kind": "customsearch#result",
218
+ "title": "Online Poker Games | Play for Free Texas Holdem | PokerStars",
219
+ "htmlTitle": "Online \u003cb\u003ePoker\u003c/b\u003e Games | Play for Free Texas Holdem | PokerStars",
220
+ "link": "http://www.pokerstars.net/",
221
+ "displayLink": "www.pokerstars.net",
222
+ "snippet": "Play Texas Hold'em poker tournaments and other free poker games at the world's largest online poker room, with PokerStars free software download.",
223
+ "htmlSnippet": "Play Texas Hold&#39;em \u003cb\u003epoker\u003c/b\u003e tournaments and other free \u003cb\u003epoker\u003c/b\u003e games at the world&#39;s \u003cbr\u003e largest online \u003cb\u003epoker\u003c/b\u003e room, with PokerStars free software download.",
224
+ "cacheId": "QMONnAr9GUMJ",
225
+ "formattedUrl": "www.pokerstars.net/",
226
+ "htmlFormattedUrl": "www.\u003cb\u003epoker\u003c/b\u003estars.net/",
227
+ "pagemap": {
228
+ "cse_image": [
229
+ {
230
+ "src": "http://www.pokerstars.net/images/nightly-500-promo-net.jpg"
231
+ }
232
+ ],
233
+ "cse_thumbnail": [
234
+ {
235
+ "width": "141",
236
+ "height": "178",
237
+ "src": "https://encrypted-tbn1.google.com/images?q=tbn:ANd9GcRiMe-aAj1GQAKfrfatZqzE3BhRT9LjXr6r5v2sVQBfWI3jYqP8m_qMrQVr"
238
+ }
239
+ ]
240
+ }
241
+ },
242
+ {
243
+ "kind": "customsearch#result",
244
+ "title": "Poker News, Online Poker Reviews & Bonuses | PokerNews",
245
+ "htmlTitle": "\u003cb\u003ePoker\u003c/b\u003e News, Online \u003cb\u003ePoker\u003c/b\u003e Reviews &amp; Bonuses | PokerNews",
246
+ "link": "http://www.pokernews.com/",
247
+ "displayLink": "www.pokernews.com",
248
+ "snippet": "PokerNews is the world's No. 1 poker information source, offering: global poker news coverage, online poker reviews, special poker bonuses and deals, ...",
249
+ "htmlSnippet": "PokerNews is the world&#39;s No. 1 \u003cb\u003epoker\u003c/b\u003e information source, offering: global \u003cb\u003epoker\u003c/b\u003e \u003cbr\u003e news coverage, online \u003cb\u003epoker\u003c/b\u003e reviews, special \u003cb\u003epoker\u003c/b\u003e bonuses and deals, \u003cb\u003e...\u003c/b\u003e",
250
+ "cacheId": "Rdd35pvFIl8J",
251
+ "formattedUrl": "www.pokernews.com/",
252
+ "htmlFormattedUrl": "www.\u003cb\u003epoker\u003c/b\u003enews.com/",
253
+ "pagemap": {
254
+ "cse_image": [
255
+ {
256
+ "src": "http://www.pokernews.com/w/articles/4f5f/91ca6bf60.jpg"
257
+ }
258
+ ],
259
+ "cse_thumbnail": [
260
+ {
261
+ "width": "276",
262
+ "height": "183",
263
+ "src": "https://encrypted-tbn1.google.com/images?q=tbn:ANd9GcQ0X_cuK9XH4Ys7UmStdrxthiQmmRbklJxCPtYQtQsnkd9pHX7Yyp3Ioro"
264
+ }
265
+ ],
266
+ "metatags": [
267
+ {
268
+ "fb:admins": "100001502531544",
269
+ "application-name": "PokerNews Global",
270
+ "msapplication-starturl": "/",
271
+ "msapplication-navbutton-color": "#000000",
272
+ "msapplication-task": "name=News;action-uri=/news/;icon-uri=/img/jumplist/news.ico"
273
+ }
274
+ ]
275
+ }
276
+ },
277
+ {
278
+ "kind": "customsearch#result",
279
+ "title": "WPT | World Poker Tour Home",
280
+ "htmlTitle": "WPT | World \u003cb\u003ePoker\u003c/b\u003e Tour Home",
281
+ "link": "http://www.worldpokertour.com/",
282
+ "displayLink": "www.worldpokertour.com",
283
+ "snippet": "Official Site. Find show and tournament information. Watch clips, view WPT player bios and statistics, improve your game, and play online.",
284
+ "htmlSnippet": "Official Site. Find show and tournament information. Watch clips, view WPT \u003cbr\u003e player bios and statistics, improve your game, and play online.",
285
+ "cacheId": "NjGERrVM5rEJ",
286
+ "formattedUrl": "www.worldpokertour.com/",
287
+ "htmlFormattedUrl": "www.world\u003cb\u003epoker\u003c/b\u003etour.com/"
288
+ }
289
+ ]
290
+ }