Парсинг, скрапинг и сбор мета-данных


Внимание! Представленные методы предназначены для анализа собственных данных, публичных страниц организаций (с их согласия) или общедоступных статистических данных. Автоматизированный сбор персональных данных (например, всех номеров телефонов пользователей ВК) нарушает 152-ФЗ «О персональных данных» и условия использования соцсетей.


Понятие парсинга и скрапинга рассмотрены в соответствующих постах, а также здесь и здесь. Процесс получения токена для парсинга социальной сети ВКонтакте описан в профильной статье. Настоятельно рекомендуем обратить внимание на раздел «Правовая основа». Понятие мета-данных раскрывается в методических рекомендациях.


Пример № 1. Парсинг открытого поста ВКонтакте (комментарии)

Что делает: Заходит в открытый пост (публичная страница/группа), собирает все комментарии, имена авторов и даты. Экспортирует в CSV.

Эффект: Получаем таблицу для анализа тональности комментариев, частоты упоминаний, выявления спама или ботов.

import requests
import csv
from datetime import datetime


ACCESS_TOKEN = "ВАШ_СЕРВИСНЫЙ_КЛЮЧ"  # Необходимо зарегистрироваться и получить
POST_URL = "https://vk.com/wall-117639365_337188"  # Пример: Администрация города Омска

# Извлекаем owner_id и post_id из URL
def extract_ids(url):
    parts = url.split('/')[-1].split('_')
    return parts[0], parts[1]

owner_id, post_id = extract_ids(POST_URL)

# Запрос к API VK
params = {
    'access_token': ACCESS_TOKEN,
    'v': '5.199',
    'owner_id': owner_id,
    'post_id': post_id,
    'count': 100,
    'extended': 1  # Получаем имена пользователей
}

response = requests.get('https://api.vk.com/method/wall.getComments', params=params)
data = response.json()

# Сохраняем в CSV
if 'response' in data:
    with open('vk_comments.csv', 'w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(['Дата', 'Имя пользователя', 'Текст комментария'])
        
        for item in data['response']['items']:
            writer.writerow([
                datetime.fromtimestamp(item['date']).strftime('%Y-%m-%d %H:%M:%S'),
                f"{item['from_id']['first_name']} {item['from_id']['last_name']}",
                item['text'].replace('\n', ' ')
            ])
    print(f"Сохранено {len(data['response']['items'])} комментариев в vk_comments.csv")
else:
    print("Ошибка:", data)

Результат: CSV-файл, который можно открыть в табличном редакторе, проанализировать результаты и построить диаграммы.


Пример № 2: Скрапинг новостного сайта с выделением сущностей (NER)

Распознавание именованных сущностей (Named Entity Recognition, NER) — задача в области обработки естественного языка (NLP), направленная на идентификацию и классификацию определённых категорий слов в тексте. Именованные сущности — это слова или словосочетания, обозначающие конкретные объекты реального мира: людей, организации, локации, даты, единицы измерения и другие категории.

Что делает: Скрапит любую публичную статью (например, Lenta.ru), извлекает из текста имена людей, организации, даты и географические названия. Использует библиотеку natasha (бесплатная, на русском языке).

Эффект: Позволяет быстро структурировать «кто, где, когда» в любом тексте — полезно для анализа угроз, фиксации фактов.


Библиотека Natasha для Python.

Natasha — это набор открытых инструментов для обработки естественного русского языка (NLP) в Python. Библиотека объединяет несколько низкоуровневых решений под единым интерфейсом и оптимизирована для работы на CPU: отличается компактным размером моделей и высокой скоростью обработки.


import requests
from bs4 import BeautifulSoup
from natasha import (
    Segmenter, NewsNERTagger, NewsEmbedding, Doc
)
import csv

# 1. Скрапим текст с новостной страницы
url = "https://lenta.ru/news/2025/04/06/example/"  # Указать реальный адрес страницы
response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})
soup = BeautifulSoup(response.text, 'html.parser')

# Находим заголовок и текст статьи (селекторы зависят от сайта)
title = soup.find('h1').get_text(strip=True)
paragraphs = soup.find_all('p')
text = title + "\n" + "\n".join([p.get_text(strip=True) for p in paragraphs])

# 2. Обрабатываем текст для выделения сущностей
segmenter = Segmenter()
emb = NewsEmbedding()
ner_tagger = NewsNERTagger(emb)

doc = Doc(text)
doc.segment(segmenter)
doc.tag_ner(ner_tagger)

# 3. Сохраняем выделенные сущности в CSV
entities = []
for span in doc.spans:
    if span.type:
        entities.append([span.text, span.type])  # type: PER (имя), ORG (организация), LOC (место)

with open('extracted_entities.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['Сущность', 'Тип'])
    writer.writerows(entities)

print(f"Извлечено {len(entities)} сущностей из статьи '{title}'")
for ent in entities[:5]:
    print(f"- {ent[0]} ({ent[1]})")

Результат: Из длинного текста мгновенно получаем таблицу типа:

  • «Сергей Иванов» (PER)
  • «Роснефть» (ORG)
  • «Москва» (LOC)
  • «25 апреля» (DATE)

Пример № 3: Сбор мета-тегов и ссылок с произвольного сайта (карта связей)

Что делает: Переходит по указанному URL, собирает все исходящие ссылки, заголовки страниц, мета-описания и ключевые слова. Строит карту связей.

Эффект: Используется для анализа «сетевой структуры» ресурса — выявления связанных сайтов (например, фишинговых сеток, перелинковки).

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
import csv

start_url = "https://example.com"  # Замените на целевую страницу
visited = set()
data = []

def scrape_meta(url):
    try:
        response = requests.get(url, timeout=5, headers={'User-Agent': 'Mozilla/5.0'})
        soup = BeautifulSoup(response.text, 'html.parser')
        
        title = soup.find('title')
        title_text = title.get_text(strip=True) if title else "Нет заголовка"
        
        description = ""
        keywords = ""
        for meta in soup.find_all('meta'):
            if meta.get('name') == 'description':
                description = meta.get('content', '')
            if meta.get('name') == 'keywords':
                keywords = meta.get('content', '')
        
        # Собираем уникальные ссылки на этой странице
        links = set()
        for a in soup.find_all('a', href=True):
            full_url = urljoin(url, a['href'])
            # Оставляем только ссылки того же домена (для карты связей)
            if urlparse(full_url).netloc == urlparse(url).netloc:
                links.add(full_url)
        
        return [url, title_text, description, keywords, len(links), str(list(links)[:5])]
    except:
        return [url, "Ошибка доступа", "", "", 0, ""]

# Скрапим не более 10 страниц (чтобы не нагружать)
urls_to_scrape = [start_url]
count = 0
while urls_to_scrape and count < 10:
    current = urls_to_scrape.pop(0)
    if current in visited:
        continue
    visited.add(current)
    data.append(scrape_meta(current))
    count += 1
    print(f"Обработано {count}: {current}")

# Сохраняем в CSV
with open('site_links_map.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['URL', 'Заголовок', 'Description', 'Keywords', 'Число ссылок', 'Примеры ссылок'])
    writer.writerows(data)

print(f"Сохранена карта из {len(data)} страниц в site_links_map.csv")

Результат: CSV с колонками — «Заголовок», «Число ссылок», «Примеры ссылок». Позволяет быстро оценить структуру сайта и перекрестные связи.


Представленные методы предназначены исключительно для работы с открытыми, общедоступными данными в рамках Федерального закона № 149-ФЗ «Об информации…». Автоматизированный сбор персональных данных без согласия субъекта запрещен 152-ФЗ «О персональных данных». Код не нарушает условия использования целевых ресурсов (например, запрет на автоматический парсинг в user‑agent ВКонтакте)