Como recolher artigos do Medium utilizando Python

Comentários: 0

Extrair artigos do Medium pode ser de extrema importância para fins como avaliação de conteúdo, coleta de dados ou monitoramento de autores e seus trabalhos. Neste tutorial, vamos aprender como extrair artigos do Medium - um site de artigos para escritores, usando a linguagem de programação python. Discutiremos como dados como o título do artigo, o nome do autor, o nome da publicação e o próprio corpo do texto podem ser extraídos de uma determinada URL de um artigo do Medium.

Requisitos

Para este tutorial, vamos extrair este artigo no Medium: "9 Python Built-in Decorators That Optimize Your Code Significantly".

Antes de começar, instale as seguintes bibliotecas:

  • Requests: Para enviar pedidos HTTP para o Medium.
  • lxml: Para analisar o conteúdo HTML.
  • Pandas: Para guardar os dados num ficheiro CSV.

Instale-os com os seguintes comandos:


pip install requests
pip install lxml 
pip install pandas

Compreender a importância dos cabeçalhos e dos proxies

O Medium usa técnicas de deteção de bots para impedir a raspagem não autorizada. Cabeçalhos e proxies adequados são cruciais para evitar a deteção de bots e para o scraping responsável.

Cabeçalhos: simulam uma solicitação como se ela viesse de um navegador real. Eles incluem informações como o tipo de navegador, tipos de conteúdo aceitos e comportamento de cache.


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: Os proxies podem mascarar o seu endereço IP, rodando-o periodicamente para tornar menos provável que os pedidos sejam bloqueados pelo Medium. Aqui está um exemplo de uso com autenticação de endereço 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
)

Envio de um pedido ao Medium

Veja como configurar os cabeçalhos e enviar uma solicitação para o URL do artigo:


import requests

# Cabeçalhos para simular um pedido real do browser
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)

Extração de dados

Assim que tivermos o conteúdo da página, podemos analisá-lo e extrair informações relevantes.

Analisando o conteúdo HTML

Usaremos o lxml para analisar a resposta HTML e extrair elementos específicos. Aqui está como fazer isso:


from lxml.html import fromstring

parser = fromstring(response.text)

# Extrair dados
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]

Agora, vamos criar um dicionário para guardar todos os dados extraídos. Isto facilita a gravação num ficheiro CSV.


# Guardar dados num dicionário
article_data = {
    'Title': title,
    'Author': author,
    'Publication': publication_name,
    'Date': publication_date,
    'Followers': auth_followers,
    'Subtitle': sub_title,
    'Content': content,
}

print(article_data)

Guardar dados num ficheiro CSV

Finalmente, vamos salvar os dados em um arquivo CSV para análise posterior ou manutenção de registros.


import pandas as pd

# Converter o dicionário em DataFrame e guardar como CSV
df = pd.DataFrame([article_data])
df.to_csv('medium_article_data.csv', index=False)
print("Data saved to medium_article_data.csv")

Código completo

Aqui está o código completo para raspar os dados do artigo do Medium:


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

# Cabeçalhos para imitar um browser
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'
}

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

# Analisar a página
parser = fromstring(response.text)

# Extrair dados
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]

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

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

A recolha de conteúdo do Medium deve ser efectuada de forma responsável. Uma carga excessiva de pedidos nos servidores pode afetar o desempenho do serviço e a recolha de dados sem autorização pode violar os termos de utilização do Web site. Verifique sempre o ficheiro robots.txt e os termos antes de fazer scraping de qualquer Web site.

Comentários:

0 Comentários