Рецепт

Пошуковик зворотних посилань на Python: список потенційних партнерів за сорок рядків

Знайдіть домени, які посилаються на ваших конкурентів, але не на вас, оцініть їх за один виклик та відсортуйте CSV. Детальний приклад із гіпотетичними даними наведено нижче.

Верстак для майстерні з інструментами для чернеток та червоною ниткою, що з'єднує точки на папері

Логіка перед кодом

Три виклики вирішують завдання. intersect приймає від двох до десяти доменів і повертає тих, хто посилається на кілька з них. refdomains для вашого сайту дає множину для віднімання. bulk_dr потім оцінює те, що залишилося.

Вартість одного запуску мінімальна, а арифметика варта того, щоб зробити її один раз. Два кредити за перетин, два за ваш власний список, один за оцінку до 2000 доменів. П'ять кредитів — це $0.0005.

Порядок має значення. Віднімайте перед оцінкою.

Люди часто спочатку оцінюють все, а потім фільтрують. Це неправильно. Оцінка коштує небагато, але вона марнує багато часу, коли CSV містить п'ятдесят тисяч рядків. Спочатку зменшіть список за перетином, запитайте DR для тих, що залишилися, і зберігайте все у звичайному словнику, щоб другий запуск міг повторно використати результат минулого дня.

prospects.py

Домени в RIVALS є заповнювачами. Імена полів зчитуються через .get, тому перевірте один сирій рядок із власного запуску, перш ніж покладатися на стовпець.

python
import csv, json, os, urllib.request as u, urllib.parse as p
KEY = os.environ['LZ_KEY']
ME = 'mysite.example'
RIVALS = ['rival-a.example', 'rival-b.example', 'rival-c.example']
def get(**kw):
    q = p.urlencode(kw)
    with u.urlopen(f'https://linkzoid.pro/api.php?{q}&key={KEY}', timeout=30) as r:
        d = json.load(r)
    if not d['ok']:
        raise SystemExit(d)
    return d
gap = get(action='intersect', q=','.join(RIVALS), per=1000)['rows']
mine = {r.get('domain') for r in get(action='refdomains', q=ME, per=1000)['rows']}
fresh = [r.get('domain') for r in gap if r.get('domain') not in mine]
scores = get(action='bulk_dr', domains=','.join(fresh[:2000]))['rows']
with open('prospects.csv', 'w', newline='') as f:
    wr = csv.writer(f)
    for row in scores:
        wr.writerow([row.get('domain'), row.get('dr')])
print(len(fresh), 'candidates')

Детальний приклад, гіпотетичні числа

Уявний запуск для невеликого нішевого блогу; ваші дані відрізнятимуться
КрокРядків на виходіКредити
перетин 3 конкурентів640 доменів2
Мінус власні доменні посилання410 залишилося2
bulk_dr для 410410 оцінено1
Зберегти DR 20 і вищеприблизно 1200
Ручна перевірка топ-3030 сторінок відкрито0

Від CSV до аутрічу, не спамлячи нікого

01

Сортування за перетином

Домени, які посилаються на два або три ваших конкурентів, мають тематичну причину посилатися на вас. Поставте їх у першу чергу.

02

Відкрийте тридцять вручну

Подивіться на сторінку, яка посилається на конкурента. Чи це список ресурсів, огляд, новина? Лише деякі з них приймають нові записи.

03

Напишіть один рядок причини

Поясніть, що ваша сторінка додає, чого немає на сторінці конкурента. Якщо ви не можете сформулювати це в одному реченні, пропустіть цей сайт.

04

Зафіксуйте, що ви надіслали

Додайте стовпці для дати, контакту та результату до того ж CSV і зафіксуйте зміни. Наступного кварталу ви подякуєте собі.

Помилки та виправлення

Скрипти пошуку часто помиляються в одних і тих же місцях
ПомилкаЧому це шкодитьВиправлення
Сортування лише за DRВеликі каталоги та скрейпери потрапляють на верхні позиціїСортувати спочатку за кількістю перетинів, потім за DR
Розсилка всьому, що перевищує порігВиглядає як спам, коштує доброго іменіВідкрийте топ-30 вручну
Ручне URL-кодуванняКоми та слеші ламають запитВикористовуйте urllib.parse.urlencode
Відправка 3000 доменів за один викликПонад ліміт у 2000Розбийте список на частини, один кредит за частину
Довіра до DR як до якостіЦе логарифмічна шкала кількості доменів, що посилаютьсяВважайте його ключем сортування, а не вердиктом
Два невеликі кущі та один великий дуб, що ділять сонячне світло в саду

Вибір конкурентів, які мають спільну аудиторію

Конкуренти визначають, що поверне перетин. Пошуковик зворотних посилань такий же ефективний, як і список, який ви йому подаєте. Три прямі конкуренти для однієї аудиторії дають чистий перетин, тоді як великий видавець, який ранжується за всіма запитами, надасть вам тисячі посилань, які нічого не кажуть про вашу сторінку.

Уявіть, що ви керуєте невеликим блогом про ремонт велосипедів. Ваші конкуренти можуть бути двома блогами про ремонт та одним магазином із сильним розділом посібників. Це чудовий набір. Додайте національний ЗМІ, і список заповниться сторінками, які ніколи не посилатимуться на блог про велосипеди.

Від двох до десяти доменів — це діапазон, який приймає ендпоінт, тому оберіть набір у межах цього діапазону. Тримайте список коротким, щоб ви могли назвати кожного конкурента з пам'яті. Короткі списки легше захищати.

Чому великі хаби забруднюють набір

Каталоги та агрегатори посилаються майже на все. Вони з'являються в кожному перетині і ховають кілька доменів, які посилаються з реальної зацікавленості. Прочитайте верхню частину відсортованого списку, перш ніж довіряти йому.

Звичайний файл виключень виправляє більшість цих проблем. Тримайте домени, яких ви ніколи не хочете бачити, в одному текстовому файлі, по одному на рядок. Завантажте його у множину та відкиньте збіги перед викликом оцінки, щоб кредити витрачалися лише на кандидатів, вартих читання.

Відокремлення конкурентів від вашого власного сайту

Ваш власний домен ніколи не має бути конкурентом. Це звучить очевидно, але скопійований список із старого проекту часто містить його, і тоді перетин повідомляє про ваші власні посилання на вас.

Помістіть конкурентів у конфігураційний словник на початку скрипта з коментарем про те, чому кожен із них там є. Наступного місяця ви згадаєте причину, і сторонній читач репозиторію теж.

Зчитування сирі рядки перед фільтрацією

Код зчитує кожне поле через .get, що запобігає збою виконання через відсутній ключ. Це також приховує неправильний ключ. Виведіть один рядок із перетину перед написанням будь-якого фільтра та подивіться на імена полів та тип кожного значення.

Оцінка, яка приходить як текст, сортується як текст, тому 9 потрапляє після 80. Перетворіть її на число один раз одразу після виклику, і решта скрипта залишиться простою.

Нормалізуйте домени перед порівнянням

Один і той самий сайт може з'явитися з префіксом www. в одному списку та без нього в іншому. Приведіть все до нижнього регістру та видаліть префікс перед порівнянням множин. Інакше ваш власний сайт може виглядати як новий кандидат.

Кінцеві слеші та випадкові пробіли зі списку, скопійованого раніше, викликають ті ж проблеми. Функція очищення в один рядок коштує менше, ніж один марний виклик оцінки.

Зберігайте датувану копію кожного запуску

Записуйте кожен запуск у файл з датою та зберігайте попередній. Тоді ви зможете відрізнити нових кандидатів від тих, яких ви вже бачили, і побачити, коли конкурент почав посилатися на нове місце.

Файли з датою також є найпростішим способом налагодження дивного результату. Відкрийте два файли поруч, і зміна зазвичай очевидна.

Оцінюйте лише те, що вижило

Пакетний виклик приймає до 2000 доменів за один кредит. Передавайте йому тих, хто вижив після віднімання, а не весь перетин. У вигаданому прикладі вище 640 рядків і 410 рядків коштують однаково оцінити за один виклик, але менший список набагато легше читати.

Кам'яні терези з латунною вагою та грубою скелею в окремих чашах

Питання перед запуском пошуковика

Більшість питань, які люди ставлять у цій частині роботи, зводяться до вартості, сортування та того, що відбувається, коли виклик завершується невдачею.

Чи коштує багато будівництво списку потенційних партнерів?

Небагато. Рецепт використовує intersect, refdomains та bulk_dr, тому п'ять кредитів за запуск у вказаному розмірі, що становить $0.0005. Повторний запуск наступного місяця коштуватиме стільки ж. Ваша власна час, витрачений на читання сторінок, — це справжня вартість.

Чому не відсортувати перетин за DR і на цьому зупинитися?

DR рахує доменні посилання за логарифмічною шкалою. Великі каталоги піднімаються на верх незалежно від їхньої релевантності, тому сортируйте спочатку за перетином і використовуйте DR як розв'язувач нічиїх, а не як основний ключ.

Чи можу я надсилати аутріч до всього в CSV?

Можете, але це погана ідея. Відкрийте сторінку, яка посилається на конкурента, вирішіть, чи підходить новий запис, і лише тоді пишіть. CSV — це шорт-лист, а не список розсилки.

Скільки конкурентів мені почати?

Три — хороший старт, у межах діапазону від двох до десяти, який приймає перетин. Додавайте більше лише тоді, коли перший запуск повертає занадто мало рядків для ранжування.

Що, якщо мій власний домен ще не має доменних посилань?

Тоді віднімання нічого не видаляє, і кожен рядок перетину стає кандидатом. Це правильно, але список буде довгим. Зменшіть його за перетином та прочитайте топ-тридцять вручну.

Чи потрібен скрипту платний ключ?

Так. Виклики intersect, refdomains та bulk_dr коштують кредитів. Безкоштовний огляд не потребує ключа, а кредит на реєстрацію в розмірі $100 покриває багато запусків такого розміру.

Перед тим, як вийде перше повідомлення

  • Відкрийте сторінку кандидата та підтвердіть, що вона посилається на конкурента, а не просто на список посилань.
  • Перевірте, чи підходить сторінка вашій аудиторії, а не лише вашому ключовому слову.
  • Видаліть будь-який домен, з яким ви вже зв'язувалися, і зафіксуйте дату поруч із ним.
  • Напишіть одне речення про те, що ваша сторінка додає, або відкиньте кандидата.
  • Надсилайте невеликими партіями, щоб відповіді можна було прочитати.

Запуск пошуковика за розкладом

Списки потенційних партнерів старіють повільніше, ніж очікують більшість людей. Щомісяця — цілком достатньо. Нові посилання від конкурента з'являються при щомісячному оновленні, тому запуск кожні кілька тижнів ловить більшість з них. Тижневі запуски переважно відтворюють файл минулого тижня, тому той самий пошуковик зворотних посилань може працювати без нагляду без великого шуму.

Розумний ритм — щомісячна оцінка та швидкий погляд на верхні рядки після кожного запуску. Тримайте крок віднімання в межах одного завдання, щоб список ніколи не містив того, що ви вже маєте.

Тримайте ключ поза файлом

Скрипт зчитує ключ із середовища, тому він ніколи не лежить у репозиторії. Встановіть LZ_KEY як секрет у вашому планувальнику або експортуйте його з файлу, який залишається поза git.

Рядок crontab може викликати той самий скрипт із змінною, встановленою перед ним. Переконайтеся, що файл, що містить ключ, має суворі дозволи на сервері.

Помилка перед записом CSV

401 або 402 має зупинити запуск, так само як і прапорець ok, який читається як false. Код видає виняток перед відкриттям файлу, тому невдалий запуск ніколи не перезапише вчорашній CSV частковим.

Логуйте витрати з кожним запуском

Кожна відповідь містить _credits, тому друкуйте баланс наприкінці завдання. За кілька місяців цей рядок покаже, чи коштує розклад стільки, скільки ви планували, і чи не почався цикл повторного отримання сторінок.

Поєднайте його з SQLite diff, якщо ви хочете історію в базі даних замість папки файлів.

Слово про те, що DR може і не може сказати

DR тут — це round(100 * log(ref_domains + 1) / log(20,000,000)). Він зростає з кількістю доменних посилань і нічим іншим. Майте це на увазі. Сайт може знаходитися на рівні 55 і все одно бути для вас марним.

Використовуйте його для ранжування, потім читайте. Подивіться, що публікує сайт, чи посилається він на сотню незв'язаних магазинів, і чи змінилося щось на ньому нещодавно. Ці перевірки займають хвилину на сайт, і жоден скрипт їх не замінить.

Коли список буде чистим, збережіть його як файл з датою та запустіть знову через місяць. Посібник дій Actions показує, як його спланувати, а порівняння n8n охоплює безкодний шлях, якщо ваша людина аутрічу віддає їй перевагу.

Примітки щодо швидкості та розміру

Кожен виклик повертає до 1000 рядків і нараховується один раз, тому прокрутка 5000 рядків перетину коштує 10 кредитів, або $0.001. Глибока пагінація зупиняється на 50 000 рядків. Використовуйте sort та order=desc на сервері, а не сортування великого списку в Python пізніше.