yelp 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE.txt +22 -504
  5. data/README.md +152 -0
  6. data/Rakefile +4 -24
  7. data/lib/yelp.rb +18 -13
  8. data/lib/yelp/burst_struct.rb +51 -0
  9. data/lib/yelp/client.rb +86 -86
  10. data/lib/yelp/configuration.rb +31 -0
  11. data/lib/yelp/endpoint/business.rb +42 -0
  12. data/lib/yelp/endpoint/search.rb +170 -0
  13. data/lib/yelp/error.rb +55 -0
  14. data/lib/yelp/version.rb +3 -0
  15. data/spec/fixtures/vcr_cassettes/business.yml +73 -0
  16. data/spec/fixtures/vcr_cassettes/search.yml +361 -0
  17. data/spec/fixtures/vcr_cassettes/search_bounding_box.yml +359 -0
  18. data/spec/fixtures/vcr_cassettes/search_by_coordinates.yml +387 -0
  19. data/spec/spec_helper.rb +14 -0
  20. data/spec/support/request_error.rb +11 -0
  21. data/spec/support/shared_configuration.rb +11 -0
  22. data/spec/yelp/burst_struct_spec.rb +124 -0
  23. data/spec/yelp/client_spec.rb +75 -0
  24. data/spec/yelp/configuration_spec.rb +44 -0
  25. data/spec/yelp/endpoint/business_spec.rb +26 -0
  26. data/spec/yelp/endpoint/search_spec.rb +72 -0
  27. data/spec/yelp/error_spec.rb +22 -0
  28. data/spec/yelp/yelp_spec.rb +10 -0
  29. data/tasks/console.rake +4 -0
  30. data/yelp.gemspec +32 -0
  31. metadata +252 -90
  32. data/CHANGELOG.rdoc +0 -48
  33. data/Manifest.txt +0 -24
  34. data/README.rdoc +0 -118
  35. data/TODO.txt +0 -6
  36. data/lib/yelp/neighborhood/request/base.rb +0 -13
  37. data/lib/yelp/neighborhood/request/geo_point.rb +0 -23
  38. data/lib/yelp/neighborhood/request/location.rb +0 -53
  39. data/lib/yelp/phone/request/number.rb +0 -24
  40. data/lib/yelp/record.rb +0 -16
  41. data/lib/yelp/request.rb +0 -44
  42. data/lib/yelp/response_format.rb +0 -36
  43. data/lib/yelp/review/request/base.rb +0 -31
  44. data/lib/yelp/review/request/bounding_box.rb +0 -37
  45. data/lib/yelp/review/request/geo_point.rb +0 -28
  46. data/lib/yelp/review/request/location.rb +0 -63
  47. data/test/test_client.rb +0 -11
  48. data/test/test_neighborhood_search.rb +0 -46
  49. data/test/test_phone_search.rb +0 -20
  50. data/test/test_review_search.rb +0 -168
  51. data/test/yelp_helper.rb +0 -45
@@ -0,0 +1,31 @@
1
+ module Yelp
2
+ class Configuration
3
+ AUTH_KEYS = [:consumer_key, :consumer_secret, :token, :token_secret]
4
+
5
+ attr_accessor *AUTH_KEYS
6
+
7
+ # Creates the configuration
8
+ # @param [Hash] hash containing configuration parameters and their values
9
+ # @return [Configuration] a new configuration with the values from the
10
+ # config_hash set
11
+ def initialize(config_hash = nil)
12
+ if config_hash.is_a?(Hash)
13
+ config_hash.each do |config_name, config_value|
14
+ self.send("#{config_name}=", config_value)
15
+ end
16
+ end
17
+ end
18
+
19
+ # Returns a hash of api keys and their values
20
+ def auth_keys
21
+ AUTH_KEYS.inject({}) do |keys_hash, key|
22
+ keys_hash[key] = send(key)
23
+ keys_hash
24
+ end
25
+ end
26
+
27
+ def valid?
28
+ AUTH_KEYS.none?{ |key| send(key).nil? || send(key).empty? }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,42 @@
1
+ require 'json'
2
+
3
+ module Yelp
4
+ module Endpoint
5
+ class Business
6
+ PATH = '/v2/business/'
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ # Make a request to the business endpoint on the API
13
+ #
14
+ # @param id [String] the business id
15
+ # @return [BurstStruct] the parsed response object from the API
16
+ #
17
+ # @example Get business
18
+ # business = client.business('yelp-san-francisco')
19
+ # business.name # => 'Yelp'
20
+ # buinesss.url # => 'http://www.yelp.com/biz/yelp-san-francisco'
21
+ def business(id)
22
+ BurstStruct::Burst.new(JSON.parse(business_request(id).body))
23
+ end
24
+
25
+ private
26
+
27
+ # Make a request to the business endpoint of the API
28
+ # The endpoint requires a format of /v2/business/{business-id}
29
+ # so the primary request parameter is concatenated. After getting
30
+ # the response back it's checked to see if there are any API errors
31
+ # and raises the relevant one if there is.
32
+ #
33
+ # @param id [String, Integer] the business id
34
+ # @return [Faraday::Response] the raw response back from the connection
35
+ def business_request(id)
36
+ result = @client.connection.get PATH + id
37
+ Error.check_for_error(result)
38
+ result
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,170 @@
1
+ require 'json'
2
+
3
+ module Yelp
4
+ module Endpoint
5
+ class Search
6
+ PATH = '/v2/search'
7
+
8
+ BOUNDING_BOX = [:sw_latitude, :sw_longitude, :ne_latitude, :ne_longitude]
9
+ COORDINATES = [:latitude, :longitude, :accuracy, :altitude, :altitude_accuracy]
10
+
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ # Take a search_request and return the formatted/structured
16
+ # response from the API
17
+ #
18
+ # @param location [String] a string location of the neighboorhood,
19
+ # address, or city
20
+ # @param params [Hash] a hash that corresponds to params on the API:
21
+ # http://www.yelp.com/developers/documentation/v2/search_api#searchGP
22
+ # @param locale [Hash] a hash that corresponds to locale on the API:
23
+ # http://www.yelp.com/developers/documentation/v2/search_api#lParam
24
+ # @return [BurstStruct::Burst] a parsed object of the response. For a complete
25
+ # list of possible response values visit:
26
+ # http://www.yelp.com/developers/documentation/v2/search_api#rValue
27
+ #
28
+ # @example Search for business with params and locale
29
+ # params = { term: 'food',
30
+ # limit: 3,
31
+ # category: 'discgolf' }
32
+ #
33
+ # locale = { lang: 'fr' }
34
+ #
35
+ # response = client.search('San Francisco', params, locale)
36
+ # response.businesses # [<Business 1>, <Business 2>, <Business 3>]
37
+ # response.businesses[0].name # 'Yelp'
38
+ #
39
+ # @example Search with only location and params
40
+ # params = { term: 'food' }
41
+ #
42
+ # response = client.search('San Francisco', params)
43
+ def search(location, params = {}, locale = {})
44
+ params.merge!(locale)
45
+ params.merge!({location: location})
46
+
47
+ BurstStruct::Burst.new(JSON.parse(search_request(params).body))
48
+ end
49
+
50
+ # Search by a bounding box: specify a south west lat/long and a ne lat/long
51
+ # along with regular parameters to make a request to the search endpoint
52
+ # More info at: http://www.yelp.com/developers/documentation/v2/search_api#searchGBB
53
+ #
54
+ # @param bounding_box [Hash] a hash of SW latitude/longitude and NE latitude/longitude,
55
+ # all 4 keys are required to be set
56
+ # @param params [Hash] a hash that corresponds to params on the API:
57
+ # http://www.yelp.com/developers/documentation/v2/search_api#searchGP
58
+ # @param locale [Hash] a hash that corresponds to locale on the API:
59
+ # http://www.yelp.com/developers/documentation/v2/search_api#lParam
60
+ # @return [BurstStruct::Burst] a parsed object of the response. For a complete
61
+ # list of possible response values visit:
62
+ # http://www.yelp.com/developers/documentation/v2/search_api#rValue
63
+ #
64
+ # @example Search for business with params and locale
65
+ # bounding_box = { sw_latitude: 37.785855, sw_longitude: -122.405780,
66
+ # ne_latitude: 37.780632, ne_longitude: -122.388442 }
67
+ #
68
+ # params = { term: 'food',
69
+ # limit: 3,
70
+ # category: 'discgolf' }
71
+ #
72
+ # locale = { lang: 'fr' }
73
+ #
74
+ # response = client.search(bounding_box, params, locale)
75
+ # response.businesses # [<Business 1>, <Business 2>, <Business 3>]
76
+ # response.businesses[0].name # 'Yelp'
77
+ #
78
+ # @example Search with only location and params
79
+ # bounding_box = { sw_latitude: 37.785855, sw_longitude: -122.405780,
80
+ # ne_latitude: 37.780632, ne_longitude: -122.388442 }
81
+ #
82
+ # params = { term: 'food' }
83
+ #
84
+ # response = client.search(bounding_box, params)
85
+ def search_by_bounding_box(bounding_box, params = {}, locale = {})
86
+ raise BoundingBoxNotComplete if BOUNDING_BOX.any? { |corner| bounding_box[corner].nil? }
87
+
88
+ options = { bounds: build_bounding_box(bounding_box) }
89
+ options.merge!(params)
90
+ options.merge!(locale)
91
+
92
+ BurstStruct::Burst.new(JSON.parse(search_request(options).body))
93
+ end
94
+
95
+ # Search by coordinates: give it a latitude and longitude along with
96
+ # option accuracy, altitude, and altitude_accuracy to search an area.
97
+ # More info at: http://www.yelp.com/developers/documentation/v2/search_api#searchGC
98
+ #
99
+ # @param coordinates [Hash] a hash of latitude, longitude, accuracy,
100
+ # altitude, and altitude accuracy. Only latitude and longitude are required
101
+ # @param params [Hash] a hash that corresponds to params on the API:
102
+ # http://www.yelp.com/developers/documentation/v2/search_api#searchGP
103
+ # @param locale [Hash] a hash that corresponds to locale on the API:
104
+ # http://www.yelp.com/developers/documentation/v2/search_api#lParam
105
+ # @return [BurstStruct::Burst] a parsed object of the response. For a complete
106
+ # list of possible response values visit:
107
+ # http://www.yelp.com/developers/documentation/v2/search_api#rValue
108
+ #
109
+ # @example Search for business with params and locale
110
+ # coordinates = { latitude: 37.786732,
111
+ # longitude: -122.399978 }
112
+ #
113
+ # params = { term: 'food',
114
+ # limit: 3,
115
+ # category: 'discgolf' }
116
+ #
117
+ # locale = { lang: 'fr' }
118
+ #
119
+ # response = client.search(coordinates, params, locale)
120
+ # response.businesses # [<Business 1>, <Business 2>, <Business 3>]
121
+ # response.businesses[0].name # 'Yelp'
122
+ #
123
+ # @example Search with only location and params
124
+ # coordinates = { latitude: 37.786732,
125
+ # longitude: -122.399978 }
126
+ #
127
+ # params = { term: 'food' }
128
+ #
129
+ # response = client.search(coordinates, params)
130
+ def search_by_coordinates(coordinates, params = {}, locale = {})
131
+ raise MissingLatLng if coordinates[:latitude].nil? || coordinates[:longitude].nil?
132
+
133
+ options = { ll: build_coordinates_string(coordinates) }
134
+ options.merge!(params)
135
+ options.merge!(locale)
136
+
137
+ BurstStruct::Burst.new(JSON.parse(search_request(options).body))
138
+ end
139
+
140
+ private
141
+
142
+ # Build the bounding box for the API. Takes in a hash of the bounding box and
143
+ # combines the coordinates into the properly formatted string
144
+ def build_bounding_box(bounding_box)
145
+ "#{bounding_box[:sw_latitude]},#{bounding_box[:sw_longitude]}|#{bounding_box[:ne_latitude]},#{bounding_box[:ne_longitude]}"
146
+ end
147
+
148
+ # Build the coordinates string for the api. Takes the hash of coordinates, loops
149
+ # over the keys in the specific order they're listed in the API docs, and builds
150
+ # that resulting string
151
+ def build_coordinates_string(coordinates)
152
+ COORDINATES.collect do |param|
153
+ coordinates[param]
154
+ end.join(',')
155
+ end
156
+
157
+ # Make a request against the search endpoint from the API and return the
158
+ # raw response. After getting the response back it's checked to see if
159
+ # there are any API errors and raises the relevant one if there is.
160
+ #
161
+ # @param params [Hash] a hash of parameters for the search request
162
+ # @return [Faraday::Response] the raw response back from the connection
163
+ def search_request(params)
164
+ result = @client.connection.get PATH, params
165
+ Error.check_for_error(result)
166
+ result
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,55 @@
1
+ module Yelp
2
+ class Error < StandardError
3
+ def self.check_for_error(data)
4
+ # Check if the status is in the range of non-error status codes
5
+ return if (200..399).include?(data.status)
6
+
7
+ body = JSON.parse(data.body)
8
+ @error_classes ||= Hash.new do |hash, key|
9
+ class_name = key.split('_').map(&:capitalize).join('').gsub('Oauth', 'OAuth')
10
+ hash[key] = Yelp.const_get(class_name)
11
+ end
12
+
13
+ klass = @error_classes[body['error']['id']]
14
+ raise klass.new(body['error']['text'])
15
+ end
16
+ end
17
+
18
+ class AlreadyConfigured < Error
19
+ def initialize(msg = 'Gem cannot be reconfigured. Initialize a new ' +
20
+ 'instance of Yelp::Client.')
21
+ super
22
+ end
23
+ end
24
+
25
+ class MissingAPIKeys < Error
26
+ def initialize(msg = "You're missing an API key")
27
+ super
28
+ end
29
+ end
30
+
31
+ class MissingLatLng < Error
32
+ def initialize(msg = 'Missing required latitude or longitude parameters')
33
+ super
34
+ end
35
+ end
36
+
37
+ class BoundingBoxNotComplete < Error
38
+ def initialize(msg = 'Missing required values for bounding box')
39
+ super
40
+ end
41
+ end
42
+
43
+ class InternalError < Error; end
44
+ class ExceededRequests < Error; end
45
+ class MissingParameter < Error; end
46
+ class InvalidParameter < Error; end
47
+ class InvalidSignature < Error; end
48
+ class InvalidOAuthCredentials < Error; end
49
+ class InvalidOAuthUser < Error; end
50
+ class AccountUnconfirmed < Error; end
51
+ class UnavailableForLocation < Error; end
52
+ class AreaTooLarge < Error; end
53
+ class MultipleLocations < Error; end
54
+ class BusinessUnavailable < Error; end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Yelp
2
+ VERSION = "2.0.0"
3
+ end
@@ -0,0 +1,73 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://api.yelp.com/v2/business/yelp-san-francisco
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.9
12
+ Authorization:
13
+ - OAuth oauth_consumer_key="<YELP_CONSUMER_KEY>", oauth_nonce="91b6047f08faeace33713a65b42cb034",
14
+ oauth_signature="yNqoLJVrdE0Ok5SwveA2lA%2BZa4U%3D", oauth_signature_method="HMAC-SHA1",
15
+ oauth_timestamp="1398701819", oauth_token="<YELP_TOKEN>", oauth_version="1.0"
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Mon, 28 Apr 2014 16:16:40 GMT
27
+ Server:
28
+ - Apache
29
+ X-Node:
30
+ - web65-r1-sfo1, api_com
31
+ Cache-Control:
32
+ - private
33
+ Set-Cookie:
34
+ - bse=2a9f068ebb71f02e3c38f8235756f6ea; Domain=.yelp.com; Path=/; HttpOnly
35
+ Content-Length:
36
+ - '2217'
37
+ Vary:
38
+ - User-Agent
39
+ Content-Type:
40
+ - application/json; charset=UTF-8
41
+ X-Mode:
42
+ - rw
43
+ X-Proxied:
44
+ - lb1
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"is_claimed": true, "rating": 2.5, "mobile_url": "http://m.yelp.com/biz/yelp-san-francisco",
48
+ "rating_img_url": "http://s3-media4.ak.yelpcdn.com/assets/2/www/img/c7fb9aff59f9/ico/stars/v1/stars_2_half.png",
49
+ "review_count": 5915, "name": "Yelp", "snippet_image_url": "http://s3-media3.ak.yelpcdn.com/photo/gNcEV7izLO97H4GS4a-UXA/ms.jpg",
50
+ "rating_img_url_small": "http://s3-media4.ak.yelpcdn.com/assets/2/www/img/8e8633e5f8f0/ico/stars/v1/stars_small_2_half.png",
51
+ "url": "http://www.yelp.com/biz/yelp-san-francisco", "reviews": [{"rating":
52
+ 1, "excerpt": "YELP has highly questionable business practices...\n\nYELP
53
+ \"goes public\" to go from swindling small business to swindling the public...\n\nYelp
54
+ has over 2...", "time_created": 1398531118, "rating_image_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f64056afac01/ico/stars/v1/stars_1.png",
55
+ "rating_image_small_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/74cb12ae7253/ico/stars/v1/stars_small_1.png",
56
+ "user": {"image_url": "http://s3-media2.ak.yelpcdn.com/photo/Lpmg6W5sqQM89qAAqocyLQ/ms.jpg",
57
+ "id": "5QWzmoRk9yXRw7712sjQTQ", "name": "Kerri G."}, "rating_image_large_url":
58
+ "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/cc5d90a21966/ico/stars/v1/stars_large_1.png",
59
+ "id": "iYSiqKNIAeMi8OIJKfc8pg"}], "phone": "4159083801", "snippet_text": "Yelp
60
+ has dramatically changed the way I do business locally and while traveling
61
+ for work or pleasure. Before making plans to eat ANYWHERE, I will scout out...",
62
+ "image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/4LSTYqXkQ-YrI1CQmr2dQA/ms.jpg",
63
+ "categories": [["Local Flavor", "localflavor"], ["Mass Media", "massmedia"]],
64
+ "display_phone": "+1-415-908-3801", "rating_img_url_large": "http://s3-media2.ak.yelpcdn.com/assets/2/www/img/d63e3add9901/ico/stars/v1/stars_large_2_half.png",
65
+ "id": "yelp-san-francisco", "is_closed": false, "location": {"cross_streets":
66
+ "Natoma St \u0026 Minna St", "city": "San Francisco", "display_address": ["140
67
+ New Montgomery St", "(b/t Natoma St \u0026 Minna St)", "Financial District",
68
+ "San Francisco, CA 94105"], "neighborhoods": ["Financial District", "SoMa"],
69
+ "postal_code": "94105", "country_code": "US", "address": ["140 New Montgomery
70
+ St"], "state_code": "CA"}}'
71
+ http_version:
72
+ recorded_at: Mon, 28 Apr 2014 16:17:05 GMT
73
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,361 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://api.yelp.com/v2/search?location=San%20Francisco
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.9
12
+ Authorization:
13
+ - OAuth oauth_consumer_key="<YELP_CONSUMER_KEY>", oauth_nonce="aef097da8356dcfae5d26850128323ba",
14
+ oauth_signature="RUhQxeFmukcYfA7IQcr8d4DphP0%3D", oauth_signature_method="HMAC-SHA1",
15
+ oauth_timestamp="1398701825", oauth_token="<YELP_TOKEN>", oauth_version="1.0"
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Mon, 28 Apr 2014 16:16:47 GMT
27
+ Server:
28
+ - Apache
29
+ X-Node:
30
+ - web72-r7-sfo1, api_com
31
+ Cache-Control:
32
+ - private
33
+ Set-Cookie:
34
+ - bse=02239fc7fddbd29057dec0153be131ec; Domain=.yelp.com; Path=/; HttpOnly
35
+ Content-Length:
36
+ - '28790'
37
+ Vary:
38
+ - User-Agent
39
+ Content-Type:
40
+ - application/json; charset=UTF-8
41
+ X-Mode:
42
+ - rw
43
+ X-Proxied:
44
+ - lb2
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"region": {"span": {"latitude_delta": 0.040105010000004881, "longitude_delta":
48
+ 0.047716677690004872}, "center": {"latitude": 37.777706649999999, "longitude":
49
+ -122.41406580105}}, "total": 40447, "businesses": [{"is_claimed": true, "rating":
50
+ 5.0, "mobile_url": "http://m.yelp.com/biz/bay-area-box-express-san-francisco-3",
51
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
52
+ "review_count": 469, "name": "Bay Area Box Express", "snippet_image_url":
53
+ "http://s3-media1.ak.yelpcdn.com/photo/TaPTZV3GYDNbp1gBzNRyxg/ms.jpg", "rating_img_url_small":
54
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
55
+ "url": "http://www.yelp.com/biz/bay-area-box-express-san-francisco-3", "phone":
56
+ "4153283832", "snippet_text": "I love to find businesses that I can put on
57
+ my special list of go-to services in an area. Bay Area Box Express is one
58
+ such business. I needed boxes for a...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/cURb4Bv-W4wJe4LuSJRYHQ/ms.jpg",
59
+ "categories": [["Movers", "movers"]], "display_phone": "+1-415-328-3832",
60
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
61
+ "id": "bay-area-box-express-san-francisco-3", "is_closed": false, "location":
62
+ {"city": "San Francisco", "display_address": ["Financial District", "San Francisco,
63
+ CA 94105"], "neighborhoods": ["Financial District", "SoMa"], "postal_code":
64
+ "94105", "country_code": "US", "address": [], "state_code": "CA"}}, {"is_claimed":
65
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/dj-jeremy-productions-san-francisco-3",
66
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
67
+ "review_count": 183, "name": "DJ Jeremy Productions", "snippet_image_url":
68
+ "http://s3-media4.ak.yelpcdn.com/photo/mCotCBB9q_YPfgMfUMvTBQ/ms.jpg", "rating_img_url_small":
69
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
70
+ "url": "http://www.yelp.com/biz/dj-jeremy-productions-san-francisco-3", "phone":
71
+ "5103902233", "snippet_text": "This review is for DJ John Piazza and the amazing
72
+ job he did at our wedding.\n\nTo start the communication beforehand was absolutely
73
+ perfect. DJ John was...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/wqq85sviWr6DCUuYrxglaA/ms.jpg",
74
+ "categories": [["DJs", "djs"]], "display_phone": "+1-510-390-2233", "rating_img_url_large":
75
+ "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
76
+ "id": "dj-jeremy-productions-san-francisco-3", "is_closed": false, "location":
77
+ {"city": "San Francisco", "display_address": ["Financial District", "San Francisco,
78
+ CA 94111"], "neighborhoods": ["Financial District"], "postal_code": "94111",
79
+ "country_code": "US", "address": [], "state_code": "CA"}}, {"is_claimed":
80
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/action-auto-care-san-francisco",
81
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
82
+ "review_count": 255, "name": "Action Auto Care", "snippet_image_url": "http://s3-media3.ak.yelpcdn.com/photo/PL-IcxQIs_pezfpft4Pq8Q/ms.jpg",
83
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
84
+ "url": "http://www.yelp.com/biz/action-auto-care-san-francisco", "phone":
85
+ "4154871210", "snippet_text": "In short -- I came in because of the reviews,
86
+ and it was worth it. Robert was extremely generous about how he charged me
87
+ for his work.\n\n----\n\nAfter Robert...", "image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/29eDpRoQK-LYZbGZz0s1-g/ms.jpg",
88
+ "categories": [["Auto Repair", "autorepair"]], "display_phone": "+1-415-487-1210",
89
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
90
+ "id": "action-auto-care-san-francisco", "is_closed": false, "location": {"cross_streets":
91
+ "Kansas St \u0026 Vermont St", "city": "San Francisco", "display_address":
92
+ ["2040 17th St", "(b/t Kansas St \u0026 Vermont St)", "Potrero Hill", "San
93
+ Francisco, CA 94103"], "neighborhoods": ["Potrero Hill"], "postal_code": "94103",
94
+ "country_code": "US", "address": ["2040 17th St"], "state_code": "CA"}}, {"is_claimed":
95
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/somafm-san-francisco",
96
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
97
+ "review_count": 201, "name": "SomaFM", "snippet_image_url": "http://s3-media4.ak.yelpcdn.com/photo/vNQ1MPneQLbMipQH7xWtjw/ms.jpg",
98
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
99
+ "url": "http://www.yelp.com/biz/somafm-san-francisco", "phone": "4158269500",
100
+ "snippet_text": "I can''t say enough good things about SOMA FM. No other
101
+ music source, with the exception of Pandora, gives me exactly what I want
102
+ to hear. They have a...", "image_url": "http://s3-media4.ak.yelpcdn.com/bphoto/QpieZO0Ln6IsflSjPk3mjw/ms.jpg",
103
+ "categories": [["Radio Stations", "radiostations"]], "display_phone": "+1-415-826-9500",
104
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
105
+ "id": "somafm-san-francisco", "is_closed": false, "location": {"cross_streets":
106
+ "19th St \u0026 20th St", "city": "San Francisco", "display_address": ["2180
107
+ Bryant St", "Ste 208", "(b/t 19th St \u0026 20th St)", "Mission", "San Francisco,
108
+ CA 94110"], "neighborhoods": ["Mission"], "postal_code": "94110", "country_code":
109
+ "US", "address": ["2180 Bryant St", "Ste 208"], "state_code": "CA"}}, {"is_claimed":
110
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/secureway-auto-glass-san-francisco",
111
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
112
+ "review_count": 386, "name": "Secureway Auto Glass", "snippet_image_url":
113
+ "http://s3-media1.ak.yelpcdn.com/photo/WLk8lAossjIro4yAk9gW3Q/ms.jpg", "rating_img_url_small":
114
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
115
+ "url": "http://www.yelp.com/biz/secureway-auto-glass-san-francisco", "phone":
116
+ "4157772222", "snippet_text": "Good service and honest.\n\nMy driver side
117
+ window had come out of alignment. I spoke with Kendall on the phone and after
118
+ explaining what was going on, she...", "image_url": "http://s3-media2.ak.yelpcdn.com/bphoto/hGECMrlHO8AOs-V1gJI6Nw/ms.jpg",
119
+ "categories": [["Auto Glass Services", "autoglass"], ["Body Shops", "bodyshops"]],
120
+ "display_phone": "+1-415-777-2222", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
121
+ "id": "secureway-auto-glass-san-francisco", "is_closed": false, "location":
122
+ {"city": "San Francisco", "display_address": ["585 Bryant St", "SoMa", "San
123
+ Francisco, CA 94107"], "neighborhoods": ["SoMa", "Mission Bay"], "postal_code":
124
+ "94107", "country_code": "US", "address": ["585 Bryant St"], "state_code":
125
+ "CA"}}, {"is_claimed": true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/cc-rider-motorcycle-tow-san-francisco-2",
126
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
127
+ "review_count": 105, "name": "CC Rider Motorcycle Tow", "snippet_image_url":
128
+ "http://s3-media1.ak.yelpcdn.com/photo/dir5n5FRoi2lKuWum4JjQA/ms.jpg", "rating_img_url_small":
129
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
130
+ "url": "http://www.yelp.com/biz/cc-rider-motorcycle-tow-san-francisco-2",
131
+ "phone": "4153348697", "snippet_text": "I just cannot give this man a four
132
+ star review even if I wanted to.\n\nI scheduled a pickup to bring down to
133
+ mission motorcycles, and it rained in SF that...", "image_url": "http://s3-media4.ak.yelpcdn.com/bphoto/M0JFvkP8EBCBaF3vmuRf2Q/ms.jpg",
134
+ "categories": [["Motorcycle Repair", "motorcyclerepair"], ["Towing", "towing"]],
135
+ "display_phone": "+1-415-334-8697", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
136
+ "id": "cc-rider-motorcycle-tow-san-francisco-2", "is_closed": false, "location":
137
+ {"city": "San Francisco", "display_address": ["162 Clara St", "SoMa", "San
138
+ Francisco, CA 94102"], "neighborhoods": ["SoMa"], "postal_code": "94102",
139
+ "country_code": "US", "address": ["162 Clara St"], "state_code": "CA"}}, {"is_claimed":
140
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/san-francisco-architecture-walking-tour-san-francisco",
141
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
142
+ "review_count": 214, "name": "San Francisco Architecture Walking Tour", "snippet_image_url":
143
+ "http://s3-media4.ak.yelpcdn.com/assets/2/www/img/cc4afe21892e/default_avatars/user_medium_square.png",
144
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
145
+ "url": "http://www.yelp.com/biz/san-francisco-architecture-walking-tour-san-francisco",
146
+ "phone": "4152648824", "snippet_text": "There are a few tours you must take
147
+ to get to know the city and this is one of them! I thought I knew SF history
148
+ but Rick taught me heaps I didn''t know. A...", "image_url": "http://s3-media2.ak.yelpcdn.com/bphoto/fwRltemE8CeB_cgxe2pu-w/ms.jpg",
149
+ "categories": [["Tours", "tours"]], "display_phone": "+1-415-264-8824", "rating_img_url_large":
150
+ "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
151
+ "id": "san-francisco-architecture-walking-tour-san-francisco", "is_closed":
152
+ false, "location": {"city": "San Francisco", "display_address": ["Galleria
153
+ Park Hotel", "191 Sutter St", "Financial District", "San Francisco, CA 94104"],
154
+ "neighborhoods": ["Financial District"], "postal_code": "94104", "country_code":
155
+ "US", "address": ["Galleria Park Hotel", "191 Sutter St"], "state_code": "CA"}},
156
+ {"is_claimed": false, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/level-6-shredding-san-francisco-2",
157
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
158
+ "review_count": 133, "name": "Level 6 Shredding", "snippet_image_url": "http://s3-media3.ak.yelpcdn.com/photo/PAis6aohiiaxDajJV5QQMQ/ms.jpg",
159
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
160
+ "url": "http://www.yelp.com/biz/level-6-shredding-san-francisco-2", "phone":
161
+ "4153411003", "snippet_text": "Summary of my experience with Level 6 Shredding:
162
+ Easy to contact and arrange appointment, courteous and pleasant to work with,
163
+ convenient and professional...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/Bajq1NnYj4queV8aoEglzw/ms.jpg",
164
+ "categories": [["Local Services", "localservices"]], "display_phone": "+1-415-341-1003",
165
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
166
+ "id": "level-6-shredding-san-francisco-2", "is_closed": false, "location":
167
+ {"cross_streets": "18th St \u0026 19th St", "city": "San Francisco", "display_address":
168
+ ["139 Collingwood St", "Ste A", "(b/t 18th St \u0026 19th St)", "Castro",
169
+ "San Francisco, CA 94114"], "neighborhoods": ["Castro"], "postal_code": "94114",
170
+ "country_code": "US", "address": ["139 Collingwood St", "Ste A"], "state_code":
171
+ "CA"}}, {"is_claimed": true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/bay-area-vdo-production-san-francisco-2",
172
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
173
+ "review_count": 96, "name": "Bay Area VDO Production", "snippet_image_url":
174
+ "http://s3-media1.ak.yelpcdn.com/photo/pLQ-QmRjo3uSu7qhRk8XOA/ms.jpg", "rating_img_url_small":
175
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
176
+ "url": "http://www.yelp.com/biz/bay-area-vdo-production-san-francisco-2",
177
+ "phone": "4155956578", "snippet_text": "I''ve been a wedding DJ for over 20
178
+ years and I choose to reserve judgement on another wedding vendor until I''ve
179
+ worked with them at least twice. In 2013, I...", "image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/xRQFbf5nfOzYDGjQutRE7Q/ms.jpg",
180
+ "categories": [["Videographers", "videographers"], ["Video/Film Production",
181
+ "videofilmproductions"]], "display_phone": "+1-415-595-6578", "rating_img_url_large":
182
+ "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
183
+ "id": "bay-area-vdo-production-san-francisco-2", "is_closed": false, "location":
184
+ {"cross_streets": "Gough St \u0026 Laguna St", "city": "San Francisco", "display_address":
185
+ ["1124 Eddy St", "(b/t Gough St \u0026 Laguna St)", "Fillmore", "San Francisco,
186
+ CA 94109"], "neighborhoods": ["Fillmore", "Western Addition"], "postal_code":
187
+ "94109", "country_code": "US", "address": ["1124 Eddy St"], "state_code":
188
+ "CA"}}, {"is_claimed": true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/ensoma-san-francisco",
189
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
190
+ "review_count": 158, "name": "Ensoma", "snippet_image_url": "http://s3-media1.ak.yelpcdn.com/photo/tHyrwwy0VLZL9sqXQ0KLdA/ms.jpg",
191
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
192
+ "url": "http://www.yelp.com/biz/ensoma-san-francisco", "phone": "4152528535",
193
+ "snippet_text": "I found Ensoma on Yelp when looking for a high quality, reasonably
194
+ priced massage to treat myself (spring break!). I couldn''t have been happier!
195
+ My...", "image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/A0opW7B_8D5x0QHohTdnYw/ms.jpg",
196
+ "categories": [["Hair Removal", "hairremoval"], ["Skin Care", "skincare"],
197
+ ["Massage", "massage"]], "display_phone": "+1-415-252-8535", "rating_img_url_large":
198
+ "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
199
+ "id": "ensoma-san-francisco", "is_closed": false, "location": {"cross_streets":
200
+ "Shipley St \u0026 Clara St", "city": "San Francisco", "display_address":
201
+ ["352 6th St", "(b/t Shipley St \u0026 Clara St)", "SoMa", "San Francisco,
202
+ CA 94103"], "neighborhoods": ["SoMa"], "postal_code": "94103", "country_code":
203
+ "US", "address": ["352 6th St"], "state_code": "CA"}}, {"is_claimed": true,
204
+ "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/euro-motorcars-san-francisco",
205
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
206
+ "review_count": 148, "name": "Euro Motorcars", "snippet_image_url": "http://s3-media4.ak.yelpcdn.com/photo/h__m6Ntl3JiOodxRaKgxhg/ms.jpg",
207
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
208
+ "url": "http://www.yelp.com/biz/euro-motorcars-san-francisco", "phone": "4152558140",
209
+ "snippet_text": "Finding an expert mechanic that is honest and fair is extremely
210
+ hard. Take your BMW to these guys - they will take care of you. Rest assured.
211
+ I recently had...", "image_url": "http://s3-media4.ak.yelpcdn.com/bphoto/uFPIkT4COJVtY37Xv8_21g/ms.jpg",
212
+ "categories": [["Auto Repair", "autorepair"]], "display_phone": "+1-415-255-8140",
213
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
214
+ "id": "euro-motorcars-san-francisco", "is_closed": false, "location": {"cross_streets":
215
+ "Clementina St \u0026 Folsom St", "city": "San Francisco", "display_address":
216
+ ["240 6th St", "(b/t Clementina St \u0026 Folsom St)", "SoMa", "San Francisco,
217
+ CA 94103"], "neighborhoods": ["SoMa"], "postal_code": "94103", "country_code":
218
+ "US", "address": ["240 6th St"], "state_code": "CA"}}, {"is_claimed": true,
219
+ "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/michael-bruno-luggage-san-francisco",
220
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
221
+ "review_count": 122, "name": "Michael Bruno Luggage", "snippet_image_url":
222
+ "http://s3-media2.ak.yelpcdn.com/photo/rIC8gDCFyTAQOrd95Q-0RA/ms.jpg", "rating_img_url_small":
223
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
224
+ "url": "http://www.yelp.com/biz/michael-bruno-luggage-san-francisco", "phone":
225
+ "4155523970", "snippet_text": "Lou is the best. He helped me find the right
226
+ travel luggage. He''s friendly and knowledgable. It''s great to see establishments
227
+ like his that still offer...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/lUmeFo-scf8sT82bEmD14Q/ms.jpg",
228
+ "categories": [["Luggage", "luggage"]], "display_phone": "+1-415-552-3970",
229
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
230
+ "id": "michael-bruno-luggage-san-francisco", "is_closed": false, "location":
231
+ {"cross_streets": "Sanchez St \u0026 16th St", "city": "San Francisco", "display_address":
232
+ ["2267 Market St", "(b/t Sanchez St \u0026 16th St)", "Castro", "San Francisco,
233
+ CA 94114"], "neighborhoods": ["Castro"], "postal_code": "94114", "country_code":
234
+ "US", "address": ["2267 Market St"], "state_code": "CA"}}, {"is_claimed":
235
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/luscious-garage-san-francisco-2",
236
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
237
+ "review_count": 154, "name": "Luscious Garage", "snippet_image_url": "http://s3-media1.ak.yelpcdn.com/photo/UUldqUxLgjvAI1m-c2O7Nw/ms.jpg",
238
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
239
+ "url": "http://www.yelp.com/biz/luscious-garage-san-francisco-2", "phone":
240
+ "4158759030", "snippet_text": "This is what a garage should be! Easy to book
241
+ appointments, follow status and pay your bill online.\n\nHad to replace a
242
+ wheel bearing and knuckle on my Prius...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/ZMQo1sRiTApQDklCV5s2sg/ms.jpg",
243
+ "categories": [["Auto Repair", "autorepair"]], "display_phone": "+1-415-875-9030",
244
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
245
+ "id": "luscious-garage-san-francisco-2", "is_closed": false, "location": {"cross_streets":
246
+ "Mclea Ct \u0026 Bryant St", "city": "San Francisco", "display_address": ["475
247
+ 9th St", "(b/t Mclea Ct \u0026 Bryant St)", "SoMa", "San Francisco, CA 94103"],
248
+ "neighborhoods": ["SoMa"], "postal_code": "94103", "country_code": "US", "address":
249
+ ["475 9th St"], "state_code": "CA"}}, {"is_claimed": true, "rating": 5.0,
250
+ "mobile_url": "http://m.yelp.com/biz/greenhearts-family-farm-csa-san-francisco",
251
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
252
+ "review_count": 77, "name": "Greenhearts Family Farm CSA", "snippet_image_url":
253
+ "http://s3-media3.ak.yelpcdn.com/photo/KfkF9oqzeYXAXcj5pxfHww/ms.jpg", "rating_img_url_small":
254
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
255
+ "url": "http://www.yelp.com/biz/greenhearts-family-farm-csa-san-francisco",
256
+ "phone": "4159715703", "snippet_text": "So I received a \"bad\" head of lettuce,
257
+ which was browning. I was sad to see this and emailed them with pictures.
258
+ After two hours, Farmer Paul informed me...", "image_url": "http://s3-media4.ak.yelpcdn.com/bphoto/zrcFSgU2ZoVzA9lqpwPdgg/ms.jpg",
259
+ "categories": [["Food Delivery Services", "fooddeliveryservices"], ["CSA",
260
+ "csa"]], "display_phone": "+1-415-971-5703", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
261
+ "id": "greenhearts-family-farm-csa-san-francisco", "is_closed": false, "location":
262
+ {"cross_streets": "Scott St \u0026 Pierce St", "city": "San Francisco", "display_address":
263
+ ["989 Oak St", "(b/t Scott St \u0026 Pierce St)", "Lower Haight", "San Francisco,
264
+ CA 94117"], "neighborhoods": ["Lower Haight"], "postal_code": "94117", "country_code":
265
+ "US", "address": ["989 Oak St"], "state_code": "CA"}}, {"is_claimed": true,
266
+ "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/emf-insurance-agency-inc-san-francisco-4",
267
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
268
+ "review_count": 106, "name": "EMF Insurance Agency, Inc", "snippet_image_url":
269
+ "http://s3-media1.ak.yelpcdn.com/photo/ee07sSPbsBAcgtrswPgyJA/ms.jpg", "rating_img_url_small":
270
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
271
+ "url": "http://www.yelp.com/biz/emf-insurance-agency-inc-san-francisco-4",
272
+ "snippet_text": "If you still think that insurance agents are sleezy suited
273
+ creatures with mounds of paperwork and heavy handed insurance language- kiss
274
+ your stereotypes...", "image_url": "http://s3-media2.ak.yelpcdn.com/bphoto/IzCxgCfX6R8aGlJ9PVDQ0A/ms.jpg",
275
+ "categories": [["Insurance", "insurance"]], "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
276
+ "id": "emf-insurance-agency-inc-san-francisco-4", "is_closed": false, "location":
277
+ {"city": "San Francisco", "display_address": ["Financial District", "San Francisco,
278
+ CA 94105"], "neighborhoods": ["Financial District", "SoMa"], "postal_code":
279
+ "94105", "country_code": "US", "address": [], "state_code": "CA"}}, {"is_claimed":
280
+ true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/captain-kirks-san-francisco-sailing-san-francisco",
281
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
282
+ "review_count": 127, "name": "Captain Kirk''s San Francisco Sailing", "snippet_image_url":
283
+ "http://s3-media1.ak.yelpcdn.com/photo/nmxgAs6IFSOhSC7HOVozEw/ms.jpg", "rating_img_url_small":
284
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
285
+ "url": "http://www.yelp.com/biz/captain-kirks-san-francisco-sailing-san-francisco",
286
+ "phone": "6504920681", "snippet_text": "I booked a trip for my team to have
287
+ a group outing. The company is very responsive, very helpful and answer questions
288
+ directly, and flexible with payment....", "image_url": "http://s3-media3.ak.yelpcdn.com/bphoto/rkr19nB6IN4cE6SlMwOsnw/ms.jpg",
289
+ "categories": [["Boating", "boating"], ["Boat Charters", "boatcharters"]],
290
+ "display_phone": "+1-650-492-0681", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
291
+ "id": "captain-kirks-san-francisco-sailing-san-francisco", "is_closed": false,
292
+ "location": {"city": "San Francisco", "display_address": ["601 Van Ness Ave",
293
+ "Suite E-736", "Fillmore", "San Francisco, CA 94102"], "neighborhoods": ["Fillmore",
294
+ "Civic Center", "Western Addition"], "postal_code": "94102", "country_code":
295
+ "US", "address": ["601 Van Ness Ave", "Suite E-736"], "state_code": "CA"}},
296
+ {"is_claimed": true, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/too-good-auto-body-repair-san-francisco",
297
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
298
+ "review_count": 88, "name": "Too Good Auto Body Repair", "snippet_image_url":
299
+ "http://s3-media2.ak.yelpcdn.com/photo/Cv3Q2LTyYkMRreSIEYTw_w/ms.jpg", "rating_img_url_small":
300
+ "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
301
+ "url": "http://www.yelp.com/biz/too-good-auto-body-repair-san-francisco",
302
+ "phone": "4154411312", "snippet_text": "When my Subaru was involved in a hit
303
+ and run, I opted out of using my insurance company''s recommended body shop,
304
+ and used Yelp to find Steve Chin and Too...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/V3ePJjLfUgGuoiROz52QtA/ms.jpg",
305
+ "categories": [["Auto Repair", "autorepair"], ["Body Shops", "bodyshops"]],
306
+ "display_phone": "+1-415-441-1312", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
307
+ "id": "too-good-auto-body-repair-san-francisco", "is_closed": false, "location":
308
+ {"cross_streets": "Franklin St \u0026 Gough St", "city": "San Francisco",
309
+ "display_address": ["1710 Pine St", "(b/t Franklin St \u0026 Gough St)", "Lower
310
+ Pacific Heights", "San Francisco, CA 94109"], "neighborhoods": ["Lower Pacific
311
+ Heights"], "postal_code": "94109", "country_code": "US", "address": ["1710
312
+ Pine St"], "state_code": "CA"}}, {"is_claimed": true, "rating": 5.0, "mobile_url":
313
+ "http://m.yelp.com/biz/2-spirit-tattoo-san-francisco", "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
314
+ "review_count": 155, "name": "2 Spirit Tattoo", "snippet_image_url": "http://s3-media2.ak.yelpcdn.com/photo/7ti3Knd192uIuLIcmRytiA/ms.jpg",
315
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
316
+ "url": "http://www.yelp.com/biz/2-spirit-tattoo-san-francisco", "phone": "4157018288",
317
+ "snippet_text": "I''ve been talking about getting a tattoo for years. I finally
318
+ decided to put up or shut up. I surveyed a bunch of places and asked anyone
319
+ with cool designs...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/G0h0yiuGDbax2r7ztWDP-w/ms.jpg",
320
+ "categories": [["Tattoo", "tattoo"], ["Art Galleries", "galleries"]], "display_phone":
321
+ "+1-415-701-8288", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
322
+ "id": "2-spirit-tattoo-san-francisco", "is_closed": false, "location": {"cross_streets":
323
+ "Pink Aly \u0026 Market St", "city": "San Francisco", "display_address": ["11
324
+ Pearl St", "(b/t Pink Aly \u0026 Market St)", "Mission", "San Francisco, CA
325
+ 94103"], "neighborhoods": ["Mission"], "postal_code": "94103", "country_code":
326
+ "US", "address": ["11 Pearl St"], "state_code": "CA"}}, {"is_claimed": true,
327
+ "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/clean-air-smog-check-star-test-only-center-san-francisco",
328
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
329
+ "review_count": 362, "name": "Clean Air Smog Check STAR Test Only Center",
330
+ "snippet_image_url": "http://s3-media1.ak.yelpcdn.com/photo/8nvLfA_vkwe50xY_F9_itA/ms.jpg",
331
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
332
+ "url": "http://www.yelp.com/biz/clean-air-smog-check-star-test-only-center-san-francisco",
333
+ "phone": "4156212983", "snippet_text": "The glowing reviews are true...Clean
334
+ Air''s service truly is quick and friendly. And, yes...as soon as you mention
335
+ Yelp they knock a big chunk off your...", "image_url": "http://s3-media1.ak.yelpcdn.com/bphoto/KAPXX_Qei1xTa8WtQ22ehw/ms.jpg",
336
+ "categories": [["Smog Check Stations", "smog_check_stations"]], "display_phone":
337
+ "+1-415-621-2983", "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
338
+ "id": "clean-air-smog-check-star-test-only-center-san-francisco", "is_closed":
339
+ false, "location": {"cross_streets": "Folsom St \u0026 Harrison St", "city":
340
+ "San Francisco", "display_address": ["368 11th St", "(b/t Folsom St \u0026
341
+ Harrison St)", "SoMa", "San Francisco, CA 94103"], "neighborhoods": ["SoMa"],
342
+ "postal_code": "94103", "country_code": "US", "address": ["368 11th St"],
343
+ "state_code": "CA"}}, {"is_claimed": false, "rating": 5.0, "mobile_url": "http://m.yelp.com/biz/kim-makoi-dc-san-francisco",
344
+ "rating_img_url": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png",
345
+ "review_count": 78, "name": "Kim Makoi, DC", "snippet_image_url": "http://s3-media1.ak.yelpcdn.com/photo/97rUSak6NXtD5KoHr3Wkag/ms.jpg",
346
+ "rating_img_url_small": "http://s3-media1.ak.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png",
347
+ "url": "http://www.yelp.com/biz/kim-makoi-dc-san-francisco", "phone": "4158642975",
348
+ "snippet_text": "What I like about Dr. Kim is that he''s holistically oriented.
349
+ He does a really thorough assessment (with lovely knowledgeable assistants!)
350
+ that helps you...", "image_url": "http://s3-media2.ak.yelpcdn.com/bphoto/qEgsajjAXy26uLJvVpCRuA/ms.jpg",
351
+ "categories": [["Chiropractors", "chiropractors"]], "display_phone": "+1-415-864-2975",
352
+ "rating_img_url_large": "http://s3-media3.ak.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png",
353
+ "id": "kim-makoi-dc-san-francisco", "is_closed": false, "location": {"cross_streets":
354
+ "Lily St \u0026 Page St", "city": "San Francisco", "display_address": ["110
355
+ Gough St", "Ste 201A", "(b/t Lily St \u0026 Page St)", "Hayes Valley", "San
356
+ Francisco, CA 94102"], "neighborhoods": ["Hayes Valley"], "postal_code": "94102",
357
+ "country_code": "US", "address": ["110 Gough St", "Ste 201A"], "state_code":
358
+ "CA"}}]}'
359
+ http_version:
360
+ recorded_at: Mon, 28 Apr 2014 16:17:06 GMT
361
+ recorded_with: VCR 2.8.0