vacancy detail SEO fix
This commit is contained in:
173
seo_helpers.py
173
seo_helpers.py
@@ -177,144 +177,71 @@ def generate_vacancy_seo_tags(vacancy_data: Dict[str, Any], vacancy_id: int) ->
|
||||
def inject_seo_tags(html_template: str, seo_tags: Dict[str, str]) -> str:
|
||||
"""
|
||||
Внедрение SEO-тегов в HTML шаблон
|
||||
|
||||
Args:
|
||||
html_template: исходный HTML
|
||||
seo_tags: словарь с SEO-тегами
|
||||
|
||||
Returns:
|
||||
HTML с замененными SEO-тегами
|
||||
"""
|
||||
replacements = {
|
||||
'<title id="pageTitle">Резюме | Rabota.Today</title>': f'<title>{seo_tags.get("title", "Rabota.Today")}</title>',
|
||||
'<title id="pageTitle">Вакансия | Rabota.Today</title>': f'<title>{seo_tags.get("title", "Rabota.Today")}</title>',
|
||||
'<meta name="description" id="metaDescription"': f'<meta name="description"',
|
||||
'<meta name="keywords"': f'<meta name="keywords"',
|
||||
'<meta property="og:title" id="ogTitle"': f'<meta property="og:title"',
|
||||
'<meta property="og:description" id="ogDescription"': f'<meta property="og:description"',
|
||||
'<meta property="og:url" id="ogUrl"': f'<meta property="og:url"',
|
||||
'<meta property="profile:first_name" id="profileFirstName"': f'<meta property="profile:first_name"',
|
||||
'<meta property="profile:last_name" id="profileLastName"': f'<meta property="profile:last_name"',
|
||||
'<meta name="twitter:title" id="twitterTitle"': f'<meta name="twitter:title"',
|
||||
'<meta name="twitter:description" id="twitterDescription"': f'<meta name="twitter:description"',
|
||||
'<link rel="canonical" id="canonicalUrl"': f'<link rel="canonical"'
|
||||
}
|
||||
|
||||
result = html_template
|
||||
|
||||
# Заменяем общие теги
|
||||
for old, new in replacements.items():
|
||||
if old in result:
|
||||
result = result.replace(old, new)
|
||||
# Заменяем title
|
||||
title_pattern = '<title id="pageTitle">.*?</title>'
|
||||
result = re.sub(title_pattern, f'<title>{seo_tags.get("title", "Rabota.Today")}</title>', result)
|
||||
|
||||
# Вставляем конкретные значения
|
||||
if 'description' in seo_tags:
|
||||
desc_pattern = '<meta name="description" content="'
|
||||
desc_start = result.find(desc_pattern)
|
||||
if desc_start != -1:
|
||||
desc_end = result.find('">', desc_start)
|
||||
if desc_end != -1:
|
||||
result = result[
|
||||
:desc_start] + f'<meta name="description" content="{seo_tags["description"]}">' + result[
|
||||
desc_end + 2:]
|
||||
# Заменяем description
|
||||
desc_pattern = '<meta name="description" id="metaDescription" content=".*?">'
|
||||
result = re.sub(desc_pattern, f'<meta name="description" content="{seo_tags.get("description", "")}">', result)
|
||||
|
||||
if 'keywords' in seo_tags:
|
||||
keywords_pattern = '<meta name="keywords" content="'
|
||||
keywords_start = result.find(keywords_pattern)
|
||||
if keywords_start != -1:
|
||||
keywords_end = result.find('">', keywords_start)
|
||||
if keywords_end != -1:
|
||||
result = result[:keywords_start] + f'<meta name="keywords" content="{seo_tags["keywords"]}">' + result[
|
||||
keywords_end + 2:]
|
||||
# Заменяем keywords
|
||||
keywords_pattern = '<meta name="keywords" id="metaKeywords" content=".*?">'
|
||||
result = re.sub(keywords_pattern, f'<meta name="keywords" content="{seo_tags.get("keywords", "")}">', result)
|
||||
|
||||
if 'og_title' in seo_tags:
|
||||
og_title_pattern = '<meta property="og:title" content="'
|
||||
og_title_start = result.find(og_title_pattern)
|
||||
if og_title_start != -1:
|
||||
og_title_end = result.find('">', og_title_start)
|
||||
if og_title_end != -1:
|
||||
result = result[
|
||||
:og_title_start] + f'<meta property="og:title" content="{seo_tags["og_title"]}">' + result[
|
||||
og_title_end + 2:]
|
||||
# Заменяем og:title
|
||||
og_title_pattern = '<meta property="og:title" id="ogTitle" content=".*?">'
|
||||
result = re.sub(og_title_pattern, f'<meta property="og:title" content="{seo_tags.get("og_title", "")}">', result)
|
||||
|
||||
if 'og_description' in seo_tags:
|
||||
og_desc_pattern = '<meta property="og:description" content="'
|
||||
og_desc_start = result.find(og_desc_pattern)
|
||||
if og_desc_start != -1:
|
||||
og_desc_end = result.find('">', og_desc_start)
|
||||
if og_desc_end != -1:
|
||||
result = result[
|
||||
:og_desc_start] + f'<meta property="og:description" content="{seo_tags["og_description"]}">' + result[
|
||||
og_desc_end + 2:]
|
||||
# Заменяем og:description
|
||||
og_desc_pattern = '<meta property="og:description" id="ogDescription" content=".*?">'
|
||||
result = re.sub(og_desc_pattern, f'<meta property="og:description" content="{seo_tags.get("og_description", "")}">',
|
||||
result)
|
||||
|
||||
if 'og_url' in seo_tags:
|
||||
og_url_pattern = '<meta property="og:url" content="'
|
||||
og_url_start = result.find(og_url_pattern)
|
||||
if og_url_start != -1:
|
||||
og_url_end = result.find('">', og_url_start)
|
||||
if og_url_end != -1:
|
||||
result = result[:og_url_start] + f'<meta property="og:url" content="{seo_tags["og_url"]}">' + result[
|
||||
og_url_end + 2:]
|
||||
# Заменяем og:url
|
||||
og_url_pattern = '<meta property="og:url" id="ogUrl" content=".*?">'
|
||||
result = re.sub(og_url_pattern, f'<meta property="og:url" content="{seo_tags.get("og_url", "")}">', result)
|
||||
|
||||
# Заменяем profile:first_name
|
||||
first_name_pattern = '<meta property="profile:first_name" id="profileFirstName" content=".*?">'
|
||||
if 'profile_first_name' in seo_tags:
|
||||
first_name_pattern = '<meta property="profile:first_name" content="'
|
||||
first_name_start = result.find(first_name_pattern)
|
||||
if first_name_start != -1:
|
||||
first_name_end = result.find('">', first_name_start)
|
||||
if first_name_end != -1:
|
||||
result = result[
|
||||
:first_name_start] + f'<meta property="profile:first_name" content="{seo_tags["profile_first_name"]}">' + result[
|
||||
first_name_end + 2:]
|
||||
result = re.sub(first_name_pattern,
|
||||
f'<meta property="profile:first_name" content="{seo_tags.get("profile_first_name", "")}">',
|
||||
result)
|
||||
|
||||
# Заменяем profile:last_name
|
||||
last_name_pattern = '<meta property="profile:last_name" id="profileLastName" content=".*?">'
|
||||
if 'profile_last_name' in seo_tags:
|
||||
last_name_pattern = '<meta property="profile:last_name" content="'
|
||||
last_name_start = result.find(last_name_pattern)
|
||||
if last_name_start != -1:
|
||||
last_name_end = result.find('">', last_name_start)
|
||||
if last_name_end != -1:
|
||||
result = result[
|
||||
:last_name_start] + f'<meta property="profile:last_name" content="{seo_tags["profile_last_name"]}">' + result[
|
||||
last_name_end + 2:]
|
||||
result = re.sub(last_name_pattern,
|
||||
f'<meta property="profile:last_name" content="{seo_tags.get("profile_last_name", "")}">',
|
||||
result)
|
||||
|
||||
if 'twitter_title' in seo_tags:
|
||||
twitter_title_pattern = '<meta name="twitter:title" content="'
|
||||
twitter_title_start = result.find(twitter_title_pattern)
|
||||
if twitter_title_start != -1:
|
||||
twitter_title_end = result.find('">', twitter_title_start)
|
||||
if twitter_title_end != -1:
|
||||
result = result[
|
||||
:twitter_title_start] + f'<meta name="twitter:title" content="{seo_tags["twitter_title"]}">' + result[
|
||||
twitter_title_end + 2:]
|
||||
# Заменяем twitter:title
|
||||
twitter_title_pattern = '<meta name="twitter:title" id="twitterTitle" content=".*?">'
|
||||
result = re.sub(twitter_title_pattern, f'<meta name="twitter:title" content="{seo_tags.get("twitter_title", "")}">',
|
||||
result)
|
||||
|
||||
if 'twitter_description' in seo_tags:
|
||||
twitter_desc_pattern = '<meta name="twitter:description" content="'
|
||||
twitter_desc_start = result.find(twitter_desc_pattern)
|
||||
if twitter_desc_start != -1:
|
||||
twitter_desc_end = result.find('">', twitter_desc_start)
|
||||
if twitter_desc_end != -1:
|
||||
result = result[
|
||||
:twitter_desc_start] + f'<meta name="twitter:description" content="{seo_tags["twitter_description"]}">' + result[
|
||||
twitter_desc_end + 2:]
|
||||
# Заменяем twitter:description
|
||||
twitter_desc_pattern = '<meta name="twitter:description" id="twitterDescription" content=".*?">'
|
||||
result = re.sub(twitter_desc_pattern,
|
||||
f'<meta name="twitter:description" content="{seo_tags.get("twitter_description", "")}">', result)
|
||||
|
||||
if 'canonical_url' in seo_tags:
|
||||
canonical_pattern = '<link rel="canonical" href="'
|
||||
canonical_start = result.find(canonical_pattern)
|
||||
if canonical_start != -1:
|
||||
canonical_end = result.find('">', canonical_start)
|
||||
if canonical_end != -1:
|
||||
result = result[
|
||||
:canonical_start] + f'<link rel="canonical" href="{seo_tags["canonical_url"]}">' + result[
|
||||
canonical_end + 2:]
|
||||
# Заменяем canonical
|
||||
canonical_pattern = '<link rel="canonical" id="canonicalUrl" href=".*?">'
|
||||
result = re.sub(canonical_pattern, f'<link rel="canonical" href="{seo_tags.get("canonical_url", "")}">', result)
|
||||
|
||||
# Вставляем структурированные данные
|
||||
if 'structured_data' in seo_tags:
|
||||
structured_pattern = '<script type="application/ld+json" id="structuredData">'
|
||||
structured_start = result.find(structured_pattern)
|
||||
if structured_start != -1:
|
||||
structured_end = result.find('</script>', structured_start)
|
||||
if structured_end != -1:
|
||||
result = result[
|
||||
:structured_start] + f'<script type="application/ld+json">\n{seo_tags["structured_data"]}\n</script>\n<script type="application/ld+json" id="structuredData" style="display:none;">' + result[
|
||||
structured_end + 9:]
|
||||
# Заменяем структурированные данные - заменяем весь блок от <script type="application/ld+json"> до </script>
|
||||
structured_pattern = r'<script type="application/ld+json">.*?</script>'
|
||||
# Находим и заменяем первый блок структурированных данных
|
||||
result = re.sub(structured_pattern,
|
||||
f'<script type="application/ld+json">\n{seo_tags.get("structured_data", "{}")}\n</script>', result,
|
||||
count=1)
|
||||
|
||||
# Удаляем второй пустой блок, если он есть
|
||||
empty_structured_pattern = r'<script type="application/ld\+json" id="structuredData" style="display:none;">\s*</script>'
|
||||
result = re.sub(empty_structured_pattern, '', result)
|
||||
|
||||
return result
|
||||
Reference in New Issue
Block a user