Explorar o mundo do web scraping pode ser um pouco intimidante. É preciso escolher a linguagem de programação certa, a biblioteca adequada e lidar com muitos contratempos imprevistos. Rapidamente, tudo isto se torna muito para assimilar. Mas não deixe que isso o desmotive! Neste artigo, respondi a algumas das perguntas mais frequentes sobre web scraping. Irá descobrir o que outras pessoas estão a fazer e os desafios que enfrentaram. Isto irá ajudá-lo a orientar o seu próprio processo de tomada de decisão. Quer seja novo na área ou um profissional experiente, há aqui algo para todos.
Porque é que o meu scraper não consegue ver os mesmos dados que o meu navegador?
Escreveu um script para obter HTML de um site, mas não está a receber os dados completos. Testou os seus seletores no navegador e eles deveriam funcionar, certo? Nem sempre. Sites que dependem de JavaScript para renderização não funcionam com uma simples solicitação GET. Existem bibliotecas como o Puppeteer e o Selenium que utilizam navegadores headless para renderizar JavaScript. Permitem-lhe fazer a solicitação no contexto de um navegador e aguardar que o JavaScript termine a execução. Desta forma, pode obter o HTML completo. Pode não precisar sempre de um navegador headless para obter os dados em falta. Procure pelas tags <script> no HTML. Os dados em falta podem estar ocultos dentro das tags <script> como variáveis JavaScript.
Como posso extrair um site que utiliza classes CSS geradas?
Alguns sites utilizam bibliotecas que criam automaticamente nomes de classes únicos para diferentes componentes da página. Isto pode dificultar a utilização de seletores CSS tradicionais para selecionar elementos específicos.
Uma solução é utilizar expressões XPath em vez disso. Os seletores XPath baseiam-se no layout da página, em vez de nomes de classes específicos. Isto significa que, mesmo que os nomes das classes mudem, o seletor XPath continuará a ser capaz de localizar o elemento desejado.
Por exemplo, se tiver um componente HTML com o seguinte aspeto:
<div class="container">
<div class="subcontainer_af21">
<ul class="ul_ax1">
<li class="li_adef">
<a href="https://link1">Winter Storm</a>
</li>
</ul>
<ul class="ul_cgt4">
<li class="li_ocv2">
<a href="https://lin2">SpaceX</a>
</li>
</ul>
</div>
</div>Pode selecionar o segundo elemento <a> com:
//div[@class='container']/div/ul[2]/li/a
O Cheerio é mais rápido do que o Puppeteer?
Sim, o Cheerio é geralmente considerado mais rápido do que o Puppeteer. Isto porque o Cheerio é uma biblioteca do lado do servidor que trabalha diretamente com o conteúdo HTML. O Puppeteer é uma biblioteca de automação de navegador que controla um navegador sem interface gráfica para carregar páginas web e interagir com elas. O Cheerio é limitado no sentido de que só pode trabalhar com páginas estáticas, não tendo a capacidade de interagir com o navegador como o Puppeteer faz
Os seletores XPath são melhores do que os seletores CSS?
Depende do contexto. Se pretende extrair dados com base na posição dos elementos, o XPath é a melhor escolha. No entanto, se pretende extrair dados com base em propriedades como classe ou id, os seletores CSS são a melhor opção.
O Playwright é melhor do que o Puppeteer?
Ambos oferecem funcionalidades semelhantes, mas o Playwright suporta vários navegadores, incluindo o Chrome, o Firefox e o Safari. O Puppeteer suporta apenas o Chrome e o Chromium.
O Playwright tem melhor suporte para trabalhar com várias abas e janelas. Também tem suporte integrado para lidar com contextos do navegador, cookies e armazenamento. O Playwright é mais adequado para projetos complexos.
Como posso evitar bloqueios de IP?
Em geral, pode tentar espaçar os seus pedidos. Use IPs diferentes. Use proxies. Tente alterar a impressão digital do navegador. Para a maioria das pessoas, esta é uma batalha sem fim. A boa notícia é que não tem de ser assim. Pode utilizar a nossa solução, a WebScrapingAPI. A WebScrapingAPI fornece uma API que tratará de todo o trabalho pesado por si. Pode executar JavaScript, alternar proxies e até lidar com CAPTCHAs. Nunca terá de se preocupar com o bloqueio do seu IP. Mas não acredite apenas na nossa palavra. Pode experimentá-la gratuitamente.
Como extrair texto de HTML com o BeautifulSoup?
Pode utilizar a biblioteca BeautifulSoup. Aqui está um exemplo de extração de texto utilizando a função .get_text():
from bs4 import BeautifulSoup
html_doc = """
<html>
<head>
<title>title of the page</title>
</head>
<body>
<p>a paragraph</p>
<a href='https://link.com'>a link</a>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
paragraph_text = soup.find('p').text
print(paragraph_text)
#Prints 'a paragraph'
link_text = soup.find('a').text
print(link_text)
#Prints 'a link'
all_text = soup.get_text()
print(all_text)
"""
title of the page
a paragraph
a link
"""Como extrair texto de HTML com o Selenium?
Veja como pode fazê-lo no Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By
DRIVER_PATH = 'path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get("https://en.wikipedia.org/wiki/Main_Page")
# get all the h2 elements
content = driver.find_element(By.TAG_NAME, "h2")
print(content.text)# Prints 'From today's featured article'
Como selecionar elementos HTML por texto com o BeautifulSoup?
Com o BeautifulSoup, pode utilizar o método soup.find com o parâmetro text=re.compile("<text>"):
from bs4 import BeautifulSoup
import re
html_doc = """
<html>
<body>
<p class="my_paragraph">a paragraph.</p>
<p class="my_paragraph">another paragraph.</p>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# find the first pTag that contains the text 'a par'
pTag = soup.find("p", text=re.compile("a par"))
print(pTag)Como selecionar elementos HTML por texto com o Selenium?
No Selenium, pode fazê-lo com o XPath:
from selenium import webdriver
from selenium.webdriver.common.by import By
DRIVER_PATH = 'path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get("https://en.wikipedia.org/wiki/Main_Page")
# get all the elements with class vector-body
span = driver.find_element(By.XPATH, "//span[contains(text(), 'Did')]")
print(span.text)
# Prints 'Did you know ...'driver.quit()
Como encontrar elementos HTML com seletores CSS no BeautifulSoup?
Veja como pode fazê-lo com o BeautifulSoup e os métodos find e find_all:
from bs4 import BeautifulSoup
html_doc = """
<html>
<body>
<p class="my_paragraph">First paragraph.</p>
<p class="my_paragraph">Second paragraph..</p>
<p>Last paragraph.</p>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# find all elements with class 'my_paragraph
elements = soup.find_all(class_="my_paragraph")
for element in elements:
print(element.text)
# prints 'First paragraph.' and 'Second paragraph..'Como encontrar elementos HTML por classe com o Selenium?
Veja como pode fazê-lo com o Selenium:
from selenium import webdriver
from selenium.webdriver.common.by import By
DRIVER_PATH = 'path/to/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get("https://en.wikipedia.org/wiki/Main_Page")
# get all the elements with class vector-body
elements = driver.find_elements(By.CLASS_NAME, "vector-body")
for element in elements:
print(element.text)
driver.quit()Como usar o XPath com o BeautifulSoup?
Vai precisar da biblioteca Python lxml:
import requests
from bs4 import BeautifulSoup
from lxml import etree
response = requests.get("https://en.wikipedia.org/wiki/Main_Page")
soup = BeautifulSoup(response.content, 'html.parser')
dom = etree.HTML(str(body))
xpath_str = '//h1//text()'
print(dom.xpath(xpath_str))
#Prints ['Main Page', 'Welcome to ', 'Wikipedia']
Como esperar que a página carregue no Selenium?
Se pretender simplesmente esperar um determinado período de tempo antes de atingir o tempo limite ao tentar localizar qualquer elemento, pode utilizar a função driver.implicitly_wait(time_in_seconds):
from selenium import webdriver
from selenium.webdriver.common.by import By
DRIVER_PATH = 'C:/Users/Michael/Desktop/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.implicitly_wait(10)
driver.get("https://en.wikipedia.org/wiki/Main_Page")
element = driver.find_element(By.ID, "not_found_id")
# the element does not exist, but it waits 10 seconds for it
text = element.text
print(text)
# Close the browserdriver.quit()
Também pode optar por esperar até que uma determinada condição seja satisfeita:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
DRIVER_PATH = 'C:/Users/Michael/Desktop/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get("https://en.wikipedia.org/wiki/Main_Page")
# Wait for the element with id 'content' to be present on the page
wait = WebDriverWait(driver, 10)
element = wait.until(EC.presence_of_element_located((By.ID, "content")))
element = driver.find_element(By.ID, "content")
text = element.text
print(text)
# Close the browserdriver.quit()
Como encontrar elementos HTML com seletores CSS no Puppeteer?
No Puppeteer, pode usar as funções page.$() e page.$$() para selecionar elementos com seletores CSS. A função page.$() é usada para encontrar o primeiro elemento que corresponda ao seletor. A função page.$$() é usada para encontrar todos os elementos que correspondam ao seletor.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto('https://www.scrapethissite.com/pages/simple/');
// Extract the first odd row element
const firstOddRow = await page.$('.container .row');
console.log(await firstOddRow.evaluate(node => node.textContent));
// Extract all the odd rows
const allOddRows = await page.$$('.container .row');
for (const oddRow of allOddRows) {
console.log(await oddRow.evaluate(node => node.textContent));
}
await browser.close();
})();Como encontrar elementos HTML com seletores CSS no Playwright?
Eis como pode fazê-lo com o Playwright. É muito semelhante ao Puppeteer:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.scrapethissite.com/pages/simple/');
// Extract the first odd row element
const firstOddRow = await page.$('.container .row');
console.log(await firstOddRow.textContent());
// Extract all the odd rows
const allOddRows = await page.$$('.container .row');
for (const oddRow of allOddRows ) {
console.log(await oddRow.textContent());
}
await browser.close();
})();Como encontrar elementos HTML com seletores CSS no cheerio?
Com o cheerio, terá de ir buscar o HTML (usei a biblioteca request para o fazer) e, em seguida, passá-lo para a biblioteca cheerio:
const request = require('request');
const cheerio = require('cheerio');
const url = 'https://www.scrapethissite.com/pages/simple/';
request(url, (error, response, html) => {
if (!error && response.statusCode === 200) {
const $ = cheerio.load(html);
const firstOddRow = $('.container .row').first();
console.log(firstOddRow.text());
const allOddRows = $('.container .row');
allOddRows.each((i, oddRow) => {
console.log($(oddRow).text());
});
}
});Como usar o XPath com o Puppeteer?
Com o Puppeteer, pode usar a função page.$x() para selecionar elementos com seletores XPath:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.scrapethissite.com/pages/forms/');
// Extract the table header elements
const allTableHeaders = await page.$x('//table/tbody/tr[1]//th');
for(let i = 0; i < allTableHeaders.length; i++) {
const header = await page.evaluate(el => el.textContent, allTableHeaders[i]);
console.log(header.trim());
}
await browser.close();
})();
// Output:
// Team Name
// Year
// Wins
// Losses
// OT Losses
// Win %
// Goals For (GF)
// Goals Against (GA)
// + / -Como usar o XPath com o Playwright?
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.scrapethissite.com/pages/forms/');
// Extract the table header elements
const allTableHeaders = await page.locator('xpath=//table/tbody/tr[1]//th').all();
for (let i = 0; i < allTableHeaders.length; i++) {
const headerText = await allTableHeaders[i].innerText();
console.log(headerText);
}
await browser.close();
})();Qualquer cadeia de caracteres de seletor que comece por // ou .. é considerada um seletor XPath. Por exemplo, o Playwright converte '//html/body' em 'xpath=//html/body'.
Como encontrar elementos HTML por texto no Puppeteer?
No Puppeteer, a forma mais simples de encontrar elementos por texto é utilizar a função XPath text():
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto('https://en.wikipedia.org/wiki/Web_scraping');
// Select all the p tags texts that contain the word "prevent"
const pTags = await page.$x('//p[contains(text(), "prevent")]/text()');
for(let i = 0; i < pTags.length; i++) {
const pTag = await page.evaluate(el => el.textContent, pTags[i]);
console.log(pTag,"\n");
}
await browser.close();
})();
//Output:
There are methods that some websites use to prevent web scraping, such as detecting and disallowing bots from crawling (viewing) their pages. In response, there are web scraping systems that rely on using techniques in ... Como encontrar elementos HTML por texto no Playwright?
Se quiser encontrar elementos por texto no Playwright, pode usar a função allInnerTexts() em combinação com o XPath.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: false,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://en.wikipedia.org/wiki/Web_scraping');
// Select all the p tags texts that contain the word "prevent"
const pTags = await page.locator('//p[contains(text(), "prevent")]').allInnerTexts();
for (let i = 0; i < pTags.length; i++) {
console.log(pTags[i], "\n");
}
await browser.close();
})();Como encontrar elementos HTML por texto no cheerio?
const request = require('request');
const cheerio = require('cheerio');
const url = 'https://en.wikipedia.org/wiki/Web_scraping';
request(url, (error, response, html) => {
if (!error && response.statusCode === 200) {
const $ = cheerio.load(html);
// Select all the p tags texts that contain the word "prevent"
const elements = $('p').filter((i, el) => $(el).text().includes('prevent'));
elements.each((i, el) => {
console.log($(el).text());
});
}
});Como aguardar seletores no Puppeteer?
No Puppeteer, pode utilizar a função page.waitForSelector() para aguardar que um elemento específico apareça na página antes de continuar com o script. Pode utilizá-la tanto com seletores CSS como com seletores XPath:
await page.waitForSelector('.basic-element', { timeout: 10000 });
await page.waitForXPath("//div[@class='basic-element']"), { timeout: 10000 });O parâmetro timeout especifica o tempo máximo de espera em ms.
Também pode aguardar que um elemento atinja um determinado estado:
await page.waitForSelector('.basic-element', { visible: true });// wait until the element becomes visible
Como esperar por seletores no Playwright?
O Playwright é semelhante ao Puppeteer. Pode utilizar o método page.waitForSelector() para aguardar que um elemento específico apareça na página.
await page.waitForSelector('.element-class', { timeout: 10000 });
Também pode esperar que um elemento atinja um determinado estado:
await page.waitForSelector('.basic-element', { state: 'visible' });// wait for element to become visible
Conclusão
O web scraping é um tema vasto e este artigo aborda apenas a superfície. Escolher a ferramenta certa para o seu caso de uso específico é crucial. Por exemplo, se quiser fazer scraping de um site usando JavaScript, a biblioteca cheerio é uma boa opção. No entanto, se o site precisar que o JavaScript carregue totalmente, o Puppeteer ou o Playwright são melhores opções. O web scraping é desafiante, mas compreender as ferramentas pode poupar-lhe muitas dores de cabeça. Espero que este artigo tenha alargado a sua perspetiva e desejo-lhe o melhor nos seus esforços de web scraping.




