{"description":"Finds businesses in a German city on Gelbe Seiten, the German business directory: name, trade, address, distance from the city centre, phone number, rating and number of reviews, whether it is open now with the opening text, and a link to the entry. Up to 50 results, in Gelbe Seiten's order. The trade must be one Gelbe Seiten knows.","effect":"read","id":"gelbeseiten.de/search-businesses","keywords":["gelbe seiten","branchenbuch","firmen","handwerker","zahnarzt","arzt","elektriker","schlüsseldienst","friseur","öffnungszeiten","telefonnummer","local business","directory","yellow pages","opening hours","near me"],"output":{"schema":{"properties":{"businesses":{"items":{"properties":{"address":{"description":"Street, postcode, city (district)","type":["string","null"]},"distance_km":{"description":"From the city centre","type":["number","null"]},"name":{"type":"string"},"open_now":{"description":"null when the entry has no opening hours","type":["boolean","null"]},"opening":{"description":"As Gelbe Seiten shows it, e.g. 'Geschlossen – Öffnet Montag um 12:00'","type":["string","null"]},"phone":{"description":"The business's public number","type":["string","null"]},"rating":{"description":"0–5, null without reviews","type":["number","null"]},"reviews":{"type":"integer"},"trade":{"type":["string","null"]},"url":{"type":"string"}},"type":"object"},"type":"array"},"total":{"type":["integer","null"]},"what":{"type":"string"},"where":{"type":"string"}},"required":["what","where","businesses"],"type":"object"},"value":"let $s = steps.search, $l = params.limit || `20` in {what: $s.what_label || params.what, where: $s.where_label || params.where, total: ($s.total && to_number(replace($s.total, '.', ''))) || `null`, businesses: map(&{name: name, trade: trade || `null`, address: (address && distance && trim(replace(address, distance, ''))) || address || `null`, distance_km: (distance && to_number(replace(replace(distance, ' km', ''), ',', '.'))) || `null`, phone: phone || `null`, rating: (rating && to_number(replace(rating, ',', '.'))) || `null`, reviews: (reviews && to_number(split(reviews, ' ')[0])) || `0`, open_now: state_class && !contains(state_class, 'geschlossen'), opening: opening || `null`, url: href}, ($l == `50` && $s.entries) || ($l == `10` && $s.entries[:10]) || ($l == `5` && $s.entries[:5]) || $s.entries[:20])}"},"params":{"additionalProperties":false,"properties":{"limit":{"default":20,"enum":[5,10,20,50],"type":"integer"},"what":{"description":"Trade or business type in German as Gelbe Seiten names it, e.g. 'zahnarzt', 'elektriker', 'schlüsseldienst', 'friseur', 'pizza lieferservice'. A term it does not know sends the page to its full-text search, which this recipe does not use (the run then fails with a redirect).","maxLength":60,"minLength":2,"type":"string"},"where":{"description":"German city, e.g. 'berlin', 'köln', 'frankfurt am main'","maxLength":60,"minLength":2,"type":"string"}},"required":["what","where"],"type":"object"},"provenance":{"method":"browser-inspect","notes":"Gelbe Seiten's search form leads to /suche/<trade>/<city>, which robots.txt disallows; the list page /branchen/<trade>/<city> (in its sitemaps, the breadcrumb target of the search page) shows the same server-rendered entries (checked: identical first 50 for zahnarzt/berlin, 1342 hits). Umlauts and spaces work URL-encoded (schlüsseldienst/frankfurt am main, elektriker/köln, pizza lieferservice/berlin). A trade the directory does not know answers 301 to /suche/<term>/<city>; the executor does not follow redirects, so such a run fails instead of returning an empty list. Each entry is article.mod-Treffer: h2 name, link to /gsbiz/<id>, best trade, rating number and count, address with distance from the search centre, an opening-state span whose class ends in --geschlossen when closed, and the phone number. Websites are base64-encoded click targets and are left out. limit is 5, 10, 20 or 50: the first entries in Gelbe Seiten's order (JMESPath slices need fixed bounds). No paid placements were marked in the list.","recorded_at":"2026-11-07T21:47:00+01:00","recorded_by":"C4"},"requires_login":false,"schema":"https://wield.run/schema/recipe/v1.json","site":{"country":"DE","id":"gelbeseiten.de","language":"de","name":"Gelbe Seiten","origin":"https://www.gelbeseiten.de","origins":["https://www.gelbeseiten.de"]},"steps":[{"description":"Gelbe Seiten's list page for a trade in a city (/branchen/<trade>/<city>, the page its sitemaps list), server-rendered with the first 50 entries.","expect":{"content_type":"html","status":[200]},"extract":{"html":{"total":{"selector":"#mod-TrefferlisteInfo"},"what_label":{"selector":"#wasBegriff"},"where_label":{"selector":"#woBegriff"}},"html_items":{"entries":{"fields":{"address":{"selector":".mod-AdresseKompakt__adress-text"},"distance":{"selector":".mod-AdresseKompakt__entfernung"},"href":{"attr":"href","selector":"a[href*='/gsbiz/']"},"name":{"selector":"h2.mod-Treffer__name"},"opening":{"selector":".oeffnungszeitKompakt__text"},"phone":{"selector":".mod-TelefonnummerKompakt__phoneNumber"},"rating":{"selector":".mod-BewertungKompakt__number"},"reviews":{"selector":".mod-BewertungKompakt__text"},"state_class":{"attr":"class","selector":"[class*='zustandsinfo--']"},"trade":{"selector":".mod-Treffer--besteBranche"}},"max":50,"selector":"article.mod-Treffer"}}},"id":"search","request":{"headers":{"Accept":"text/html"},"method":"GET","url":"/branchen/{{params.what | trim | lower | urlencode}}/{{params.where | trim | lower | urlencode}}"}}],"task":"Find local businesses by trade and city","tos":{"notes":"Uses the /branchen list pages robots.txt allows, not the disallowed /suche path. One request per call; no e-mail, chat or call actions. Business phone numbers and addresses are the public entries Gelbe Seiten publishes.","reviewed":false},"verify":{"checks":["length(output.businesses) == `20`","output.total > `500`","length(output.businesses[?starts_with(url, 'https://www.gelbeseiten.de/gsbiz/')]) == length(output.businesses)","length(output.businesses[?phone != `null`]) > `15`","length(output.businesses[?contains(address, 'Berlin')]) == length(output.businesses)","length(output.businesses[?rating != `null` && (rating > `5` || rating < `0`)]) == `0`"],"example_params":{"what":"zahnarzt","where":"berlin"},"max_ms":4000},"version":1}