Описание
Мотивация
- Тематическое обсуждение: Википедия:Запросы_к_ботоводам/Архив/2019/3#Очистить_UTM-метки_—_2
- Тематическое обсуждение: Википедия:Форум/Архив/Технический/2017/06#UTM_parameters
UTM-метки являются служебной информацией и не влияют на попадание в целевую страницу. Соответственно, их содержимое избыточно. Более того, эти значения описывают маркетинговые элементы распространения информации.
Реализация
Бот ищет контекстно UTM-параметры, и удаляет их из текста вместе со значениями параметров URL.
Синтаксический разбор идёт от имени параметра до концовки - это один из символов '&', ' ', '\n', '\r', '<', ']'
.
Список удаляемых параметров:
- utm_source
- utm_medium
- utm_content
- utm_referrer
- utm_campaign
- utm_term
- utm
- utm_cid
- utm_hp_ref
Помимо классических UTM-меток, добавлены аналогичные других ресурсов (пример fbclid от Фейсбука):
- fbclid
- yclid
- gclid
- igshid
Исходный код
import mwparserfromhell
from processing.options.options_impl import get_options
TASK_UTM = "UTM-метки"
def process_utm_for_http_text(http_text):
utms = ["utm_source", "utm_medium", "utm_content", "utm_referrer", "utm_campaign", "utm_term", "utm", "utm_cid",
"utm_hp_ref", "yclid", "gclid", "fbclid", "igshid"]
if "utm." in http_text:
return http_text
if not ("&utm" in http_text or "?utm" in http_text or "clid" in http_text or "shid" in http_text):
return http_text
text = http_text
changed = False
for one_utm in utms:
while one_utm in text:
pos = text.find(one_utm)
end = pos + 1
pos = pos - 1
while True:
if end >= len(text):
break
if text[end] in ['&', '\n', '\r', '<', ']', ' ']:
break
end += 1
if end > len(text):
continue
if end == len(text):
text = text[:pos]
changed = True
continue
if text[end] in ['.']:
break
if text[pos] == '?' and text[end] == '&':
pos += 1
end += 1
text = text[:pos] + text[end:]
changed = True
if changed:
return text
return http_text
def process_utm(text):
# in templates
parsed = mwparserfromhell.parse(text)
for template in parsed.ifilter_templates():
for param in template.params:
value = template.get(param.name).value.strip()
if "http:" not in value and "https:" not in value:
continue
utmed_text = process_utm_for_http_text(value)
if utmed_text != value:
template.get(param.name).value = utmed_text
output = str(parsed)
text = output
# in text-ref's
pairs = {
'http://': [' ', '</ref>'],
'https://': [' ', '</ref>']
}
for start, finish in pairs.items():
pos = 0
while True:
pos = text.find(start, pos)
if pos != -1:
end = -1
for f in finish:
i_end = text.find(f, pos)
if i_end != -1:
if end == -1:
end = i_end
else:
if i_end < end:
end = i_end
if end != -1:
value = text[pos:end]
utmed_text = process_utm_for_http_text(value)
if utmed_text != value:
text = text[:pos] + utmed_text + text[end:]
else:
pos = end
else:
break
else:
break
return text
def utm_for_article(text, title="unknown"):
options = get_options()
exceptions = options.get("статьи")["исключить_если_есть_в_названии"]['utm']
if title in exceptions:
return text
return process_utm(text)
Тестирование
from text_processing.utm import process_utm
def test_utm():
assert process_utm(
'<ref>{{cite web|url=http://www.bashinform.ru/news/?yn&utm_source=yxnews&utm_medium=desktop&utm_referrer=https%3A%2F%2Fyandex.ru%2Fnews Информация ИА «Башинформ»}}</ref>') == \
'<ref>{{cite web|url=http://www.bashinform.ru/news/?yn& Информация ИА «Башинформ»}}</ref>'
assert process_utm(
'<ref>{{cite web|url=https://auto.rambler.ru/roadaccidents/ Далее: https://auto.rambler.ru/roadaccidents/42930390/?utm_content=rauto&utm_medium=read_more&utm_source=copylink}}</ref>') == \
'<ref>{{cite web|url=https://auto.rambler.ru/roadaccidents/ Далее: https://auto.rambler.ru/roadaccidents/42930390/?}}</ref>'
assert process_utm(
'<ref>{{cite web|url=https://tass.ru/mezhdunarodnaya-panorama/6992630?utm_referrer=https%3A%2F%2Fzen.yandex.com%2F%3Ffrom%3Dspecial&utm_source=YandexZenSpecial Турция и сирийская оппозиция захватили город Рас-эль-Айн в Сирии}}</ref>') == \
'<ref>{{cite web|url=https://tass.ru/mezhdunarodnaya-panorama/6992630? Турция и сирийская оппозиция захватили город Рас-эль-Айн в Сирии}}</ref>'
assert process_utm(
'<ref>{{cite web|url=https://tass.ru/opinions/7118243?utm_source=yxnews&utm_medium=desktop&utm_referrer=https%3A%2F%2Fyandex.ru%2Fnews |title= Боливия без Моралеса. Почему никто пока не смог успокоить волнения в этой стране |author= Юрьева Дарья|date=|work=|publisher= ТАСС |accessdate= 2019-11-14|lang= |archiveurl=https://web.archive.org/web/20191116085511/https://tass.ru/opinions/7118243?utm_source=yxnews&utm_medium=desktop&utm_referrer=https://yandex.ru/news|archivedate=2019-11-16|deadlink=no}}</ref>') == \
'<ref>{{cite web|url=https://tass.ru/opinions/7118243?|title= Боливия без Моралеса. Почему никто пока не смог успокоить волнения в этой стране |author= Юрьева Дарья|date=|work=|publisher= ТАСС |accessdate= 2019-11-14|lang= |archiveurl=https://web.archive.org/web/20191116085511/https://tass.ru/opinions/7118243?|archivedate=2019-11-16|deadlink=no}}</ref>'
assert process_utm(
'http://www.bashinform.ru/news/?yn&utm_source=yxnews&utm_medium=desktop&utm_referrer=https%3A%2F%2Fyandex.ru%2Fnews Информация ИА «Башинформ»') == \
'http://www.bashinform.ru/news/?yn& Информация ИА «Башинформ»'
assert process_utm(
'<ref>http://www.bashinform.ru/news/?yn&utm_source=yxnews&utm_medium=desktop&utm_referrer=https%3A%2F%2Fyandex.ru%2Fnews</ref>') == \
'<ref>http://www.bashinform.ru/news/?yn&</ref>'
Состояние и развитие
- Тестирование. Bsivko (обс.) 09:51, 1 ноября 2019 (UTC)
- Что есть обработано и поставлено в боевой режим. Bsivko (обс.) 14:37, 1 ноября 2019 (UTC)
- В последние пару недель были найдены случаи ложного срабатывания. В связи с этим изменилась форма поиска — на поля шаблонов, содержащих ссылки (URL) и
<ref>
'ы. Помимо этого, добавлены на удаление параметры utm_cid
и utm_hp_ref
. Bsivko (обс.) 14:02, 28 декабря 2019 (UTC)
- Добавлены метки других ресурсов:
fbclid
, yclid
, gclid
. Bsivko (обс.) 19:22, 30 января 2020 (UTC)
- Добавлена метка инстаграмма (igshid). Bsivko (обс.) 10:09, 8 июля 2020 (UTC)
Обсуждение