Jak skrobać artykuły z Medium przy użyciu Pythona

Komentarze: 0

Wyodrębnianie artykułów z Medium może mieć ogromne znaczenie dla celów takich jak ocena treści, gromadzenie danych lub monitorowanie autorów i ich prac. W tym samouczku dowiemy się, jak zeskrobać medium - witrynę z artykułami dla pisarzy, używając języka programowania Python. Omówimy, w jaki sposób dane takie jak tytuł artykułu, nazwisko autora, nazwa publikacji i sama treść tekstu mogą zostać wyodrębnione z danego adresu URL artykułu na Medium.

Wymagania

W tym samouczku będziemy skrobać ten artykuł na Medium: "9 wbudowanych dekoratorów Pythona, które znacznie optymalizują Twój kod".

Zanim zaczniesz, zainstaluj następujące biblioteki:

  • Requests: Aby wysyłać żądania HTTP do Medium.
  • lxml: For parsing HTML content.
  • Pandas: Aby zapisać dane w pliku CSV.

Zainstaluj je za pomocą następujących poleceń:


pip install requests
pip install lxml 
pip install pandas

Zrozumienie znaczenia nagłówków i serwerów proxy

Medium wykorzystuje techniki wykrywania botów, aby zapobiec nieautoryzowanemu skrobaniu. Właściwe nagłówki i serwery proxy mają kluczowe znaczenie dla uniknięcia wykrywania botów i odpowiedzialnego skrobania.

Headers: Symulują one żądanie tak, jakby pochodziło z prawdziwej przeglądarki. Obejmują one informacje takie jak typ przeglądarki, akceptowane typy treści i zachowanie buforowania.


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',
}

Proxy: Serwery proxy mogą maskować adres IP, zmieniając go okresowo, aby zmniejszyć prawdopodobieństwo zablokowania żądań przez Medium. Oto przykład użycia z uwierzytelnianiem adresu IP:


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

response = requests.get(
 'https://medium.com/techtofreedom/9-python-built-in-decorators-that-optimize-your-code-significantly-bc3f661e9017',
    headers=headers,
    proxies=proxies
)

Wysłanie żądania do Medium

Oto jak skonfigurować nagłówki i wysłać żądanie do adresu URL artykułu:


import requests

# Nagłówki symulujące rzeczywiste żądanie przeglądarki
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://medium.com/techtofreedom/9-python-built-in-decorators-that-optimize-your-code-significantly-bc3f661e9017'
response = requests.get(url, headers=headers)

Wyodrębnianie danych

Gdy mamy już zawartość strony, możemy ją przeanalizować i wyodrębnić istotne informacje.

Parsowanie zawartości HTML

Użyjemy lxml do przeanalizowania odpowiedzi HTML i wyodrębnienia określonych elementów. Oto jak to zrobić:


from lxml.html import fromstring

parser = fromstring(response.text)

# Wyodrębnianie danych
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]

Teraz utworzymy słownik do przechowywania wszystkich wyodrębnionych danych. Ułatwi to zapisywanie do pliku CSV.


# Zapisywanie danych w słowniku
article_data = {
    'Title': title,
    'Author': author,
    'Publication': publication_name,
    'Date': publication_date,
    'Followers': auth_followers,
    'Subtitle': sub_title,
    'Content': content,
}

print(article_data)

Zapisywanie danych do pliku CSV

Na koniec zapiszmy dane do pliku CSV w celu dalszej analizy lub prowadzenia dokumentacji.


import pandas as pd

# Konwertowanie słownika na DataFrame i zapisywanie jako CSV
df = pd.DataFrame([article_data])
df.to_csv('medium_article_data.csv', index=False)
print("Data saved to medium_article_data.csv")

Pełny kod

Oto kompletny kod do skrobania danych artykułu Medium:


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

# Nagłówki naśladujące przeglądarkę
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'
}

# Żądanie strony
url = 'https://medium.com/techtofreedom/9-python-built-in-decorators-that-optimize-your-code-significantly-bc3f661e9017'
response = requests.get(url, headers=headers, proxies=proxies)

# Analizowanie strony
parser = fromstring(response.text)

# Wyodrębnianie danych
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]

# Zapisywanie danych
article_data = {
    'Title': title,
    'Author': author,
    'Publication': publication_name,
    'Date': publication_date,
    'Followers': auth_followers,
    'Subtitle': sub_title,
    'Content': content,
}

# Zapisz do CSV
df = pd.DataFrame([article_data])
df.to_csv('medium_article_data.csv', index=False)
print("Data saved to medium_article_data.csv")

Pobieranie treści z Medium powinno być przeprowadzane w sposób odpowiedzialny. Nadmierne obciążenie serwerów żądaniami może wpłynąć na wydajność usługi, a skrobanie danych bez pozwolenia może naruszać warunki korzystania z witryny. Zawsze sprawdzaj plik robots.txt i warunki przed skrobaniem jakiejkolwiek witryny.

Komentarze:

0 komentarze