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 +4 -0
- data/CHANGELOG.rdoc +2 -0
- data/Gemfile.lock +38 -0
- data/LICENSE +20 -0
- data/README.md +126 -0
- data/Rakefile +19 -0
- data/lib/google_custom_search_api.rb +107 -0
- data/lib/version.rb +3 -0
- data/spec/fixtures/empty.json +31 -0
- data/spec/fixtures/poker.json +290 -0
- data/spec/fixtures/poker_81.json +302 -0
- data/spec/fixtures/poker_91.json +238 -0
- data/spec/google_custom_search_api_spec.rb +46 -0
- data/spec/spec_helper.rb +14 -0
- metadata +134 -0
data/.gitignore
ADDED
data/CHANGELOG.rdoc
ADDED
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,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 & 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'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 & 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'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'em \u003cb\u003epoker\u003c/b\u003e tournaments and other free \u003cb\u003epoker\u003c/b\u003e games at the world'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 & 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'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
|
+
}
|