Uma capacidade importante para obter dados de páginas web é o web scraping. O Pinterest e o Instagram, que carregam conteúdo dinamicamente através da interação dos utilizadores com eles, são exemplos deste tipo de sítios Web. Os métodos regulares de raspagem são insuficientes ao lidar com material baseado em JavaScript. Neste artigo, vamos falar sobre o Playwright como ferramenta de automação, enquanto o lxml será usado para extração de dados desses sites dinâmicos que exigem Javascript para funcionar corretamente. Nesse sentido, podemos discutir a utilização de proxies no Playwright para evitar a deteção de bots. Neste tutorial, vamos raspar o perfil do Instagram para recuperar todos os URLs de posts, simulando o comportamento do usuário, como rolar e esperar que os posts sejam carregados.
Ferramentas que usaremos neste guia:
Vamos ilustrar o processo usando o exemplo de raspagem de um perfil do Instagram para extrair URLs de postagens, simulando ações do usuário, como rolar a página e aguardar o carregamento de novos dados. Os sites dinâmicos carregam seu conteúdo de forma assíncrona por meio de solicitações AJAX, o que significa que nem todo o conteúdo da página está imediatamente acessível.
Antes de começarmos, instale os pacotes necessários:
pip install playwright
pip install lxml
Também é necessário instalar os navegadores Playwright:
playwright install
Usaremos o Playwright para automatizar o navegador, carregar o conteúdo dinâmico do Instagram e percorrer a página para carregar mais posts. Vamos criar um script de automação básico:
Script de automação (navegador sem cabeça):
import asyncio
from playwright.async_api import async_playwright
async def scrape_instagram():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True) # Modo sem cabeça Sem feedback visual
page = await browser.new_page()
# Visite o URL do perfil
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Clique no botão para carregar mais mensagens
await page.get_by_role("button", name="Show more posts from").click()
# Percorrer a página para carregar conteúdo dinâmico
scroll_count = 5 # Personalize esta opção com base no número de vezes que pretende deslocar-se
for _ in range(scroll_count):
await page.evaluate('window.scrollBy(0, 700);')
await page.wait_for_timeout(3000) # Aguardar que as mensagens sejam carregadas
await page.wait_for_load_state("networkidle")
# Obter o conteúdo da página
content = await page.content()
await browser.close()
return content
# Executar a função assíncrona
asyncio.run(scrape_instagram())
Depois que o conteúdo é carregado, podemos usar lxml para analisar o HTML e extrair dados usando XPath. Neste caso, estamos extraindo as URLs de todos os posts do perfil.
Analisando o conteúdo da página e extraindo URLs de publicações:
from lxml import html
import json
def extract_post_urls(page_content):
# Analisar o conteúdo HTML utilizando lxml
tree = html.fromstring(page_content)
# XPath para extrair URLs de posts
post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
# Extrair URLs
post_urls = tree.xpath(post_urls_xpath)
# Converter URLs relativos em absolutos
base_url = "https://www.instagram.com"
post_urls = [f"{base_url}{url}" for url in post_urls]
return post_urls
Exemplo de função para guardar os dados extraídos no formato JSON:
def save_data(profile_url, post_urls):
data = {profile_url: post_urls}
with open('instagram_posts.json', 'w') as json_file:
json.dump(data, json_file, indent=4)
# Recolher e extrair URLs
page_content = asyncio.run(scrape_instagram())
post_urls = extract_post_urls(page_content)
# Guardar os URLs extraídos num ficheiro JSON
save_data("https://www.instagram.com/profile name/", post_urls)
Para raspar sites dinâmicos, muitas vezes é necessário simular a rolagem infinita. Em nosso script, rolamos a página usando JavaScript:
(window.scrollBy(0, 700))
E aguarde que o novo conteúdo seja carregado utilizando este comando:
wait_for_load_state("networkidle")
O Instagram tem limites de taxa rigorosos e medidas anti-bot. Para evitar ser bloqueado, você pode usar proxies para alternar endereços IP e distribuir solicitações. O Playwright facilita a integração de proxies na sua automação de raspagem.
Implementando proxies no Playwright:
async def scrape_with_proxy():
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy={"server": "http://your-proxy-server:port"}
)
page = await browser.new_page()
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Continuar a raspar como antes...
O Playwright também suporta que o proxy seja passado como nome de utilizador e palavra-passe e o exemplo do servidor é dado abaixo.
async def scrape_with_proxy():
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy={"server": "http://your-proxy-server:port", "username": "username", "password": "password"}
)
page = await browser.new_page()
await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
# Continuar a raspar como antes...
Os proxies ajudam a evitar proibições de IP, desafios CAPTCHA e garantem a raspagem suave de sites com muitos dados ou restritos, como o Instagram.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json
# Função para automatizar o navegador e extrair conteúdos dinâmicos com proxies
async def scrape_instagram(profile_url, proxy=None):
async with async_playwright() as p:
# Configurar o browser com proxy, se fornecido
browser_options = {
'headless': True, # Utilizar o navegador principal para ver a ação (pode ser definido como Verdadeiro para o modo sem cabeça)
}
if proxy:
browser_options['proxy'] = proxy
# Iniciar o browser
browser = await p.chromium.launch(**browser_options)
page = await browser.new_page()
# Visitar a página de perfil do Instagram
await page.goto(profile_url, wait_until="networkidle")
# Tente clicar no botão "Mostrar mais mensagens" (opcional, pode falhar se o botão não for encontrado)
try:
await page.click('button:has-text("Show more posts from")')
except Exception as e:
print(f"No 'Show more posts' button found: {e}")
# Percorrer a página para carregar mais mensagens
scroll_count = 5 # Número de deslocações para carregar mensagens
for _ in range(scroll_count):
await page.evaluate('window.scrollBy(0, 500);')
await page.wait_for_timeout(3000) # Aguardar que as novas mensagens sejam carregadas
await page.wait_for_load_state("networkidle")
# Obter o conteúdo completo da página após a deslocação
content = await page.content()
await browser.close() # Fechar o navegador quando terminar
return content
# Função para analisar o conteúdo da página recolhida e extrair os URLs dos posts
def extract_post_urls(page_content):
# Analisar o conteúdo HTML utilizando lxml
tree = html.fromstring(page_content)
# XPath para extrair URLs de posts
post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
# Extrair URLs de posts utilizando o XPath
post_urls = tree.xpath(post_urls_xpath)
# Converter URLs relativos em URLs absolutos
base_url = "https://www.instagram.com"
post_urls = [f"{base_url}{url}" for url in post_urls]
return post_urls
# Função para guardar os URLs dos posts extraídos num ficheiro JSON
def save_data(profile_url, post_urls):
# Estruturar os dados no formato JSON
data = {profile_url: post_urls}
# Guardar os dados num ficheiro
with open('instagram_posts.json', 'w') as json_file:
json.dump(data, json_file, indent=4)
print(f"Data saved to instagram_posts.json")
# Função principal para executar o raspador e guardar os dados
async def main():
# Definir o URL do perfil do Instagram
profile_url = "https://www.instagram.com/profile name/"
# Opcionalmente, configure um proxy
proxy = {"server": "server", "username": "username", "password": "password"} # Use None if no proxy is required
# Extrair a página do Instagram com proxies
page_content = await scrape_instagram(profile_url, proxy=proxy)
# Extrair URLs de posts do conteúdo da página raspada
post_urls = extract_post_urls(page_content)
# Guardar os URLs de publicação extraídos num ficheiro JSON
save_data(profile_url, post_urls)
if __name__ == '__main__':
asyncio.run(main())
Embora o Playwright seja uma excelente opção para raspar sites dinâmicos, outras ferramentas podem ser adequadas para diferentes cenários:
Cada ferramenta oferece pontos fortes únicos e pode ser escolhida com base nas necessidades e condições específicas do projeto.
Para uma raspagem bem-sucedida de sites dinâmicos que usam ativamente solicitações JavaScript e AJAX, são necessárias ferramentas poderosas capazes de lidar eficientemente com rolagem infinita e elementos interativos complexos. Uma dessas soluções é o Playwright - uma ferramenta da Microsoft que fornece automação completa do navegador, tornando-a uma escolha ideal para plataformas como o Instagram. Combinado com a biblioteca lxml para análise de HTML, o Playwright simplifica bastante a extração de dados, permitindo a automatização de interações com elementos da página e o processo de análise sem intervenção manual. Além disso, o uso de servidores proxy ajuda a contornar a proteção anti-bot e evita o bloqueio de IP, garantindo operações de raspagem estáveis e ininterruptas.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Comentários: 0