Як скрапити статті на ресурсі Medium з використанням Python

Коментарі: 0

Витяг статей з Medium може бути важливим для оцінки контенту, збору даних або моніторингу авторів та їхніх робіт. У цьому посібнику розглядається процес скрапінгу Medium - сайту для письменників, з використанням мови програмування Python. Обговорюється методика вилучення даних, таких як назва статті, ім'я автора, назва публікації та текст з URL статті на Medium.

Предустановки

В цій інструкції буде проводитися скрапінг наступної статті на Medium: "9 Python Built-in Decorators That Optimize Your Code Significantly".

Перед початком встановіть такі бібліотеки:

  • Requests: Для надсилання HTTP-запитів на Medium;
  • lxml: Для парсингу HTML-контенту;
  • Pandas: Для збереження даних у файл CSV.

Встановіть їх за допомогою таких команд:


pip install requests
pip install lxml 
pip install pandas

Важливість використання заголовків і проксі-серверів

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

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


headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

Проксі маскують IP-адресу, а якщо її періодично змінювати, це зменшує ймовірність блокування запитів до Medium. Приклад використання з авторизацією за IP-адресою:


proxies = {
    'http': 'IP:PORT',
    'https': 'IP:PORT'
}

response = requests.get(
 'Https URL',
    headers=headers,
    proxies=proxies
)

Відправлення запиту на Medium

Нижче представлено як налаштувати заголовки та надіслати запит на URL статті:


import requests

# Заголовки для імітації запиту від реального браузера
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}

url = 'https ссылка'
response = requests.get(url, headers=headers)

Витяг даних

Отримавши вміст сторінки, можна провести його парсинг і витягти релевантну інформацію.

Парсинг HTML-контенту

Для парсингу HTML-відповіді та вилучення конкретних елементів буде використовуватися бібліотека lxml. Ось як це можна зробити:


from lxml.html import fromstring

parser = fromstring(response.text)

# Витяг даних
title = parser.xpath('//h1[@data-testid="storyTitle"]/text()')[0]
author = parser.xpath('//a[@data-testid="authorName"]/text()')[0]
publication_name = parser.xpath('//a[@data-testid="publicationName"]/p/text()')[0]
publication_date = parser.xpath('//span[@data-testid="storyPublishDate"]/text()')[0]
content = '\n '.join(parser.xpath('//div[@class="ci bh ga gb gc gd"]/p/text()'))
auth_followers = parser.xpath('//span[@class="pw-follower-count bf b bg z bk"]/a/text()')[0]
sub_title = parser.xpath('//h2[@id="1de6"]/text()')[0]

Тепер ми створимо словник для зберігання всіх витягнутих даних. Це полегшить подальше збереження в CSV-файл.


# Збереження даних у словник
article_data = {
    'Title': title,
    'Author': author,
    'Publication': publication_name,
    'Date': publication_date,
    'Followers': auth_followers,
    'Subtitle': sub_title,
    'Content': content,
}

print(article_data)

Збереження даних у файл CSV

Далі збережемо дані у файл CSV для подальшого аналізу або архівування.


import pandas as pd

# Перетворення словника в DataFrame і збереження в CSV
df = pd.DataFrame([article_data])
df.to_csv('medium_article_data.csv', index=False)
print("Data saved to medium_article_data.csv")

Фінальний код

Повний код для скрапінгу даних статей із Medium виглядає так:


import requests
from lxml.html import fromstring
import pandas as pd

# Заголовки для імітації реального браузера
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-language': 'en-IN,en;q=0.9',
    'cache-control': 'no-cache',
    'dnt': '1',
    'pragma': 'no-cache',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Linux"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'none',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36',
}


proxies = {
    'http': 'IP:PORT',
    'https': 'IP:PORT'
}

# Надсилання запиту
url = 'https cсылка'
response = requests.get(url, headers=headers, proxies=proxies)

# Парсинг сторінки
parser = fromstring(response.text)

# Витяг даних
title = parser.xpath('//h1[@data-testid="storyTitle"]/text()')[0]
author = parser.xpath('//a[@data-testid="authorName"]/text()')[0]
publication_name = parser.xpath('//a[@data-testid="publicationName"]/p/text()')[0]
publication_date = parser.xpath('//span[@data-testid="storyPublishDate"]/text()')[0]
content = '\n '.join(parser.xpath('//div[@class="ci bh ga gb gc gd"]/p/text()'))
auth_followers = parser.xpath('//span[@class="pw-follower-count bf b bg z bk"]/a/text()')[0]
sub_title = parser.xpath('//h2[@id="1de6"]/text()')[0]

# Збереження даних
article_data = {
    'Title': title,
    'Author': author,
    'Publication': publication_name,
    'Date': publication_date,
    'Followers': auth_followers,
    'Subtitle': sub_title,
    'Content': content,
}

# Збереження в CSV
df = pd.DataFrame([article_data])
df.to_csv('medium_article_data.csv', index=False)
print("Data saved to medium_article_data.csv")

Скрапінг контенту з Medium має проводитися відповідально. Надмірне навантаження запитами на сервери може вплинути на роботу сервісу, а скрапінг даних без дозволу може порушувати умови використання сайту. Завжди перевіряйте файл robots.txt і умови перед скрапінгом будь-якого веб-сайту.

Коментарії:

0 Коментаріїв