Le scraping va au-dela de BeautifulSoup sur un site statique. En entretien Data Engineer Senior, on evalue la capacite a gerer les sites dynamiques, la grande echelle et les contraintes legales.
Le scraping est un outil puissant mais qui engage la responsabilite du developpeur. En entretien, on ne teste pas seulement la technique — on verifie aussi la connaissance des limites legales et ethiques.
Quelle est la difference entre le crawling et le scraping ? Et l automatisation web ?
| Outil | Statique | Dynamique | Masse | Ideal pour |
|---|---|---|---|---|
| BeautifulSoup + requests | Oui | Non | Non | Pages statiques simples, prototypage |
| Playwright | Oui | Oui | Moyen | Sites dynamiques JS, automatisation UI |
| Selenium | Oui | Oui | Non | Sites dynamiques, tests UI (plus lent que Playwright) |
| Scrapy | Oui | Partiel | Oui | Scraping massif, pipelines de production |
| httpx + asyncio | Oui | Non | Oui | Requetes paralleles a haute performance |
Pourquoi Playwright est-il prefere a Selenium en 2025 ? Quand utilisez-vous l un ou l autre ?
from playwright.async_api import async_playwright
import asyncio
async def scrape_spa():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
# Intercepter les requetes reseau
page.on('response', lambda r: print(r.url) if '/api/' in r.url else None)
await page.goto('https://exemple.com/products')
# Attendre que les donnees soient chargees
await page.wait_for_selector('.product-card', timeout=10000)
products = await page.query_selector_all('.product-card')
data = []
for p_elem in products:
name = await p_elem.query_selector('.title')
price = await p_elem.query_selector('.price')
data.append({
'name': await name.inner_text(),
'price': await price.inner_text()
})
await browser.close()
return data
asyncio.run(scrape_spa())import scrapy
class ProductSpider(scrapy.Spider):
name = 'products'
start_urls = ['https://exemple.com/catalogue']
custom_settings = {
'DOWNLOAD_DELAY': 1.5, # politesse
'ROBOTSTXT_OBEY': True, # respecte robots.txt
'AUTOTHROTTLE_ENABLED': True, # adaptation automatique
'ITEM_PIPELINES': {
'myproject.pipelines.DatabasePipeline': 300,
}
}
def parse(self, response):
for product in response.css('.product-card'):
yield {
'name': product.css('.title::text').get(),
'price': product.css('.price::text').get(),
'url': product.css('a::attr(href)').get()
}
# Pagination automatique
next_page = response.css('a.next::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)| Niveau | Maitrise | Signal GO | NO-GO |
|---|---|---|---|
| Junior | BeautifulSoup + requests, pagination, gestion erreurs | A scrape un site avec pagination, verifie robots.txt | Ne verifie pas robots.txt, ne gere pas les erreurs HTTP |
| Confirme | Playwright pour les SPA, Scrapy, anti-detection basique | Sait quand utiliser Playwright, a un projet Scrapy | Ne sait pas gerer les sites dynamiques JS |
| Senior | Proxies rotatifs, pipeline industrialise, aspects legaux maitrise | Cite spontanement les risques RGPD et la legislation, a deploye un scraper en production avec Airflow | Ne mentionne pas les aspects legaux |
Premier entretien gratuit. Rapport GO/NO-GO sous 48h.