LinkedIn — одна из самых ценных платформ для HR-аналитики, исследования рынка труда и конкурентного анализа. Но платформа активно защищает свои данные от автоматизированного сбора. В этом руководстве мы разберём, как работать только с публично доступными данными, соблюдая правовые и этические границы.
Важное предупреждение: Эта статья посвящена исключительно сбору публично доступных данных без авторизации. Мы не обсуждаем методы обхода защит, сбора приватных данных или использования учётных записей для автоматизированного доступа. Всегда консультируйтесь с юристом перед запуском проектов по сбору данных. Соблюдайте robots.txt, условия использования платформ и применимое законодательство (CFAA в США, GDPR в ЕС).
Правовой контекст: дело hiQ Labs v. LinkedIn
В 2017 году LinkedIn направил компании hiQ Labs письмо о прекращении сбора данных с платформы. hiQ подала встречный иск, утверждая, что публично доступные данные не защищены законом CFAA (Computer Fraud and Abuse Act).
В 2019 году федеральный суд вынес предварительный судебный запрет в пользу hiQ, постановив, что сбор публично доступных данных не нарушает CFAA. В 2022 году Апелляционный суд девятого округа подтвердил, что доступ к публичным данным без авторизации не является «без разрешения» в смысле CFAA.
Однако это не carte blanche для любого сбора данных:
- Решение касается только публично доступных профилей
- LinkedIn продолжает совершенствовать технические меры защиты
- Нарушение ToS может повлечь гражданскую ответственность
- GDPR и другие законы о конфиденциальности добавляют дополнительные ограничения
Мы не даём юридических советов. Дело hiQ создаёт прецедент, но каждая ситуация уникальна. Проконсультируйтесь с юристом.
Какие данные LinkedIn доступны без авторизации
Без входа в систему LinkedIn предоставляет ограниченный набор данных:
Публичные профили
URL-адреса вида linkedin.com/in/username показывают базовую информацию:
- Имя и фамилия
- Заголовок (текущая должность)
- Географическое местоположение
- Текущая и прошлые компании (частично)
- Образование (частично)
LinkedIn намеренно ограничивает полноту данных для неавторизованных посетителей.
Страницы компаний
Страницы linkedin.com/company/name доступны публично:
- Название компании и описание
- Отрасль и размер
- Местоположение штаб-квартиры
- Количество сотрудников (приблизительно)
- Последние публикации
Публичные вакансии
Страницы вакансий linkedin.com/jobs/view/ID доступны без входа:
- Название должности
- Компания-работодатель
- Местоположение
- Описание вакансии
- Требуемый опыт и навыки
Почему residential-прокси необходимы
LinkedIn применяет агрессивные меры против автоматизированного доступа:
| Метод защиты | Как работает | Почему DC-прокси не подходят |
|---|---|---|
| IP-фингерпринтинг | Блокирует диапазоны IP дата-центров | DC-IP легко идентифицируются |
| Rate limiting | Ограничивает запросы с одного IP | Один DC-IP быстро блокируется |
| Browser fingerprinting | Анализирует User-Agent, заголовки, JS-отпечаток | Требует реалистичного браузера |
| Behavioural analysis | Обнаруживает паттерны ботов | Автоматические запросы подозрительны |
Residential-прокси используют IP-адреса реальных домашних устройств. LinkedIn видит запросы как исходящие от обычных пользователей, что значительно снижает риск блокировки.
Ключевые преимущества residential-прокси для LinkedIn:
- Массовая ротация IP — каждый запрос с нового адреса
- Географическое распределение — запросы из разных регионов выглядят органично
- Низкий риск блокировки — IP не находятся в чёрных списках дата-центров
Для задач, требующих стабильной сессии (например, пагинация вакансий), используйте sticky-сессии residential-прокси.
Пример реализации: Python + Playwright с residential-прокси
Playwright обеспечивает реалистичный браузерный контекст, что критически важно для обхода fingerprinting. Вот пример сбора публичного профиля:
import asyncio
import random
import time
from playwright.async_api import async_playwright
# Конфигурация ProxyHat residential proxy
PROXY_HOST = "gate.proxyhat.com"
PROXY_PORT = 8080
PROXY_USER = "user-country-US" # Ротация по странам
PROXY_PASS = "your_password"
async def fetch_linkedin_profile(profile_url: str) -> dict:
"""Извлекает данные из публичного профиля LinkedIn."""
proxy_url = f"http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"
async with async_playwright() as p:
browser = await p.chromium.launch(
proxy={"server": proxy_url},
headless=True
)
# Создаём реалистичный контекст браузера
context = await browser.new_context(
viewport={"width": 1920, "height": 1080},
user_agent=(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
),
locale="en-US",
timezone_id="America/New_York"
)
page = await context.new_page()
try:
# Случайная задержка для имитации человека
await asyncio.sleep(random.uniform(2, 5))
await page.goto(profile_url, wait_until="networkidle", timeout=30000)
# Извлекаем публичные данные
data = await page.evaluate("""() => {
const name = document.querySelector('h1')?.innerText || '';
const headline = document.querySelector('.text-body-medium')?.innerText || '';
const location = document.querySelector('.inline-show-more-text--is-collapsed')?.innerText || '';
return { name, headline, location };
}""")
return data
except Exception as e:
print(f"Error fetching {profile_url}: {e}")
return None
finally:
await browser.close()
# Пример использования
async def main():
profiles = [
"https://www.linkedin.com/in/some-public-profile/",
# Добавьте реальные публичные URL
]
for url in profiles:
data = await fetch_linkedin_profile(url)
if data:
print(f"Profile: {data}")
# Критически важная задержка между запросами
await asyncio.sleep(random.uniform(10, 30))
asyncio.run(main())
Ключевые практики безопасности
- Ограничьте скорость — максимум 10–20 запросов в час с одного IP
- Ротируйте IP — используйте разные residential-адреса для каждого запроса
- Случайные задержки — имитируйте человеческое поведение
- Реалистичный User-Agent — соответствующий вашей версии браузера
- Уважайте robots.txt — проверяйте директивы перед сбором
Скрейпинг вакансий LinkedIn
Поиск вакансий — одна из самых востребованных задач для аналитики рынка труда. LinkedIn предоставляет публичный доступ к вакансиям через URL-параметры.
Структура URL для поиска вакансий
https://www.linkedin.com/jobs/search/?
keywords=software+engineer&
location=San+Francisco&
f_JT=F& # Тип занятости: F=Full-time
f_E=2& # Уровень опыта: 2=Mid-Senior
start=0 # Пагинация: 0, 25, 50, ...
Пример скрейпинга вакансий
import requests
from bs4 import BeautifulSoup
import time
import random
# ProxyHat residential proxy
PROXIES = {
"http": "http://user-country-US:password@gate.proxyhat.com:8080",
"https": "http://user-country-US:password@gate.proxyhat.com:8080"
}
def search_linkedin_jobs(keyword: str, location: str, max_pages: int = 3):
"""Поиск вакансий на LinkedIn."""
base_url = "https://www.linkedin.com/jobs/search/"
jobs = []
for page in range(max_pages):
params = {
"keywords": keyword,
"location": location,
"start": page * 25 # LinkedIn показывает 25 вакансий на страницу
}
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36"
),
"Accept-Language": "en-US,en;q=0.9"
}
try:
response = requests.get(
base_url,
params=params,
proxies=PROXIES,
headers=headers,
timeout=30
)
if response.status_code == 429:
print("Rate limited. Waiting...")
time.sleep(300) # 5 минут ожидания
continue
soup = BeautifulSoup(response.text, "html.parser")
# Извлечение карточек вакансий
job_cards = soup.select(".job-search-card")
for card in job_cards:
job = {
"title": card.select_one("h3")?.text.strip(),
"company": card.select_one("h4")?.text.strip(),
"location": card.select_one(".job-search-card__location")?.text.strip(),
"url": card.select_one("a")?.get("href")
}
jobs.append(job)
print(f"Page {page + 1}: found {len(job_cards)} jobs")
# Случайная задержка между страницами
time.sleep(random.uniform(15, 45))
except Exception as e:
print(f"Error on page {page}: {e}")
return jobs
# Использование
jobs = search_linkedin_jobs(
keyword="data engineer",
location="Germany",
max_pages=3
)
print(f"Total jobs found: {len(jobs)}")
Фильтры поиска вакансий
| Параметр | Описание | Примеры значений |
|---|---|---|
| f_JT | Тип занятости | F (full-time), P (part-time), C (contract) |
| f_E | Уровень опыта | 1 (entry), 2 (mid), 3 (senior) |
| f_WT | Тип работы | 1 (on-site), 2 (remote), 3 (hybrid) |
| f_I | Отрасль | Код отрасли LinkedIn |
| distance | Радиус поиска | 25, 50, 100 (км/мили) |
Когда НЕ следует скрейпить LinkedIn
Существуют чёткие границы, которые нельзя пересекать:
Приватные данные
Любые данные, требующие входа в систему:
- Сообщения и InMail
- Соединения (connections) пользователя
- Полные профили контактов
- Рекомендации и навыки
Sales Navigator
Платные функции LinkedIn полностью закрыты:
- Расширенные фильтры поиска
- Lead recommendations
- Account insights
- InMail credits
Данные, защищённые GDPR
Даже публичные данные могут быть защищены GDPR:
- Персональная информация жителей ЕС
- Данные, которые субъект не ожидал увидеть собранными
- Информация, используемая для автоматического принятия решений
Признаки того, что вы нарушаете границы
- Вы используете учётные данные для автоматизированного доступа
- Вы обходите CAPTCHA или другие механизмы защиты
- Вы собираете данные, не видимые в обычном браузере
- Вы не уважаете robots.txt
- Вы не предоставляете возможность opt-out
Альтернативы: официальные API LinkedIn
LinkedIn предоставляет несколько официальных API для различных сценариев:
LinkedIn Marketing API
Для рекламных и маркетинговых интеграций:
- Управление рекламными кампаниями
- Аналитика аудитории
- Lead Gen Forms
LinkedIn Talent Solutions API
Для рекрутеров и HR-платформ:
- Публикация вакансий
- Управление кандидатами
- Интеграция с ATS-системами
Требует партнёрского соглашения с LinkedIn.
LinkedIn Learning API
Для интеграции корпоративного обучения:
- Доступ к курсам
- Прогресс обучения
- Сертификаты
Сравнение подходов
| Аспект | Официальный API | Скрейпинг публичных данных |
|---|---|---|
| Легальность | Полностью законно | Зависит от юрисдикции |
| Стабильность | Гарантирована LinkedIn | Может измениться без предупреждения |
| Ограничения | По партнёрскому соглашению | Технические меры защиты |
| Стоимость | Часто платное партнёрство | Затраты на прокси и разработку |
| Полнота данных | Ограничена API | Только публичные данные |
Этические принципы сбора данных
При любом проекте по сбору данных следуйте этим принципам:
- Минимизация данных — собирайте только то, что действительно нужно
- Прозрачность — чётко укажите цели использования данных
- Уважение к конфиденциальности — предоставляйте возможность opt-out
- Безопасность — защищайте собранные данные от утечек
- Соблюдение законодательства — GDPR, CCPA, локальные законы
Ключевые выводы
- Публичные данные — профили, вакансии и страницы компаний доступны без авторизации, но в ограниченном объёме
- Residential-прокси обязательны — LinkedIn агрессивно блокирует DC-IP и использует продвинутый fingerprinting
- Дело hiQ Labs — создаёт прецедент для публичных данных, но не отменяет осторожности
- Строгое ограничение скорости — максимум 10–20 запросов в час с одного IP
- Никаких приватных данных — не собирайте информацию, требующую входа в систему
- Рассмотрите официальные API — для production-систем это надёжнее
Готовы начать работу с residential-прокси? Изучите тарифы ProxyHat и доступные локации для оптимального географического распределения запросов.
Для дополнительных сценариев использования прокси ознакомьтесь с нашими руководствами по веб-скрейпингу и SERP-мониторингу.






