Yelp

search-businesses

yelp.com
InstallationInstalls just this skill for your agent
Side effectread
Authnone
Needsnavigate · evaluate
Summary

Search Yelp for local businesses by term and location, with rating and price.

Params
{"query":"string (what to search, e.g. 'coffee' or 'plumber')","location":"string (city or address, e.g. 'San Francisco, CA')"}
Returns
{"count":"int","results":"array of { name, slug, url, rating, reviews, price }"}
SKILL.md42 lines

Intent

Search Yelp for local businesses by term and location. Navigates the search results page and reads the rendered business cards in the browser (Yelp's DOM is obfuscated, so this keys off the stable /biz/ heading links and the star-rating aria-labels). Params: query (e.g. 'coffee' or 'plumber'), location (city or address, e.g. 'San Francisco, CA'). Returns {count, results:[{name, slug, url, rating, reviews, price}]}. Read-only.

Execute

  1. navigate → https://www.yelp.com/search?find_desc={{query|encode}}&find_loc={{location|encode}}
  2. evaluate the Extractor below with params. It does the in-page work and returns the JSON in returns.

Extractor

( async (root, params) => { const doc = root && root.querySelectorAll ? root : document; const txt = (el) => el ? (el.innerText || el.textContent || '').trim() : null; const heads = Array.from(doc.querySelectorAll('h3 a[href*="/biz/"], h4 a[href*="/biz/"]')); const seen = new Set(); const results = []; for (const a of heads) { const slug = ((a.getAttribute('href') || '').split('/biz/')[1] || '').split('?')[0].split('/')[0]; if (!slug || seen.has(slug)) continue; seen.add(slug); let card = a; for (let i = 0; i < 10 && card.parentElement; i++) { card = card.parentElement; if (card.querySelector('[aria-label*="star rating"]')) break; } const ratingEl = card.querySelector('[aria-label*="star rating"]'); const rm = ratingEl ? (ratingEl.getAttribute('aria-label') || '').match(/([\d.]+)/) : null; let reviews = null; const revEl = card.querySelector('[aria-label$="reviews"], [aria-label$="review"]'); if (revEl) { const n = (revEl.getAttribute('aria-label') || '').replace(/[^\d]/g, ''); if (n) reviews = parseInt(n, 10); } if (reviews == null) { const mm = (txt(card) || '').match(/(?([\d,]{1,7}))?\s*(?:reviews?|reseñas?)/i); if (mm) reviews = parseInt(mm[1].replace(/[^\d]/g, ''), 10); } const priceEl = Array.from(card.querySelectorAll('span')).find((s) => /^$+$/.test(txt(s) || '')); results.push({ name: txt(a), slug, url: 'https://www.yelp.com/biz/' + slug, rating: rm ? parseFloat(rm[1]) : null, reviews, price: priceEl ? txt(priceEl) : null }); } return { count: results.length, results }; } )

Success assertion

{
  "expr": "typeof result === 'object' && Array.isArray(result.results)",
  "type": "value"
}