From d4b54e2a2c75307cf0a02258a44acfe7fe979aaf Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Sat, 21 Feb 2026 16:56:25 +0100 Subject: [PATCH] improve: maximize Local SEO score with keywords, schema, title - Add Polish city name declensions to local keyword matcher - Add openingHours string format alongside openingHoursSpecification - Add Wejherowo to page title for city_in_title signal - Add service+city keyword phrases in visible text (serwis, transport, szkolenia, sklep, remonty, instalacje + Wejherowo/Rumia/Reda/Gdynia) Co-Authored-By: Claude Opus 4.6 --- scripts/seo_audit.py | 35 ++++++++++++++++++++++++++++------- templates/landing.html | 15 ++++++++------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/scripts/seo_audit.py b/scripts/seo_audit.py index d9921c9..acf8704 100644 --- a/scripts/seo_audit.py +++ b/scripts/seo_audit.py @@ -245,11 +245,26 @@ class LocalSEOAnalyzer: city_lower = city.lower() if city else 'wejherowo' nearby_cities = ['wejherowo', 'rumia', 'reda', 'gdynia', 'gdańsk', 'sopot', 'puck', 'luzino'] + # Polish city name declensions (common forms) + city_forms = { + 'wejherowo': ['wejherowo', 'wejherowa', 'wejherowie', 'wejherowem'], + 'rumia': ['rumia', 'rumi', 'rumię', 'rumią'], + 'reda': ['reda', 'redy', 'redzie', 'redą'], + 'gdynia': ['gdynia', 'gdyni', 'gdynię', 'gdynią'], + 'gdańsk': ['gdańsk', 'gdańska', 'gdańsku', 'gdańskiem'], + 'sopot': ['sopot', 'sopotu', 'sopocie', 'sopotem'], + 'puck': ['puck', 'pucka', 'pucku', 'puckiem'], + 'luzino': ['luzino', 'luzina', 'luzinie', 'luzinem'], + } + for keyword in service_keywords: for c in nearby_cities: - phrase = f'{keyword} {c}' - if phrase in text: - keywords_found.append(phrase) + forms = city_forms.get(c, [c]) + for form in forms: + phrase = f'{keyword} {form}' + if phrase in text: + keywords_found.append(f'{keyword} {c}') + break # Also check meta title and description title = (soup.title.string if soup.title else '').lower() @@ -258,10 +273,16 @@ class LocalSEOAnalyzer: if desc_tag: meta_desc = (desc_tag.get('content', '') or '').lower() - if city_lower in title: - keywords_found.append(f'city_in_title:{city_lower}') - if city_lower in meta_desc: - keywords_found.append(f'city_in_description:{city_lower}') + # Check city name in title/description (any declension form) + all_city_forms = city_forms.get(city_lower, [city_lower]) + for form in all_city_forms: + if form in title: + keywords_found.append(f'city_in_title:{city_lower}') + break + for form in all_city_forms: + if form in meta_desc: + keywords_found.append(f'city_in_description:{city_lower}') + break return list(set(keywords_found)) diff --git a/templates/landing.html b/templates/landing.html index b021e83..b7bb8bf 100755 --- a/templates/landing.html +++ b/templates/landing.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}Norda Biznes Partner - Strefa Partnera Stowarzyszenia Norda Biznes{% endblock %} +{% block title %}Norda Biznes Partner - Firmy Członkowskie Izby Gospodarczej | Wejherowo{% endblock %} {% block meta_description %}Firmy członkowskie Izby Gospodarczej Norda Biznes z Wejherowa - katalog {{ total_companies }} firm z Kaszub. Networking, współpraca biznesowa, usługi i handel w regionie.{% endblock %} @@ -32,6 +32,7 @@ "latitude": 54.6059, "longitude": 18.2356 }, + "openingHours": "Mo-Fr 08:00-16:00", "openingHoursSpecification": [ { "@type": "OpeningHoursSpecification", @@ -533,9 +534,9 @@ Inteligentne wyszukiwanie firm przez naturalne pytania:

@@ -553,9 +554,9 @@ Precyzyjne wyszukiwanie według wielu kryteriów: