Cu fundamentele atât ale scraping-ului de conținut static, cât și dinamic sub centura noastră, este timpul să abordăm o provocare mai cuprinzătoare: crawling-ul multi-pagină. Această secțiune se concentrează pe navigarea eficientă și extragerea datelor din site-uri web cu multiple pagini interconectate.
Există două abordări principale pentru crawling-ul site-urilor multi-pagină:
- Crawling bazat pe link-uri - Urmărirea link-urilor între pagini
- Crawling bazat pe sitemap - Folosirea fișierului sitemap.xml
Pentru crawling-ul sitemap, majoritatea site-urilor oferă un fișier sitemap.xml care listează toate URL-urile importante. Acest fișier XML structurat include:
- URL-uri de pagini
- Date de ultimă modificare
- Frecvența schimbărilor
- Valori de prioritate
Folosirea sitemap-ului poate fi mai eficientă decât crawling-ul pe link-uri pentru că:
- Oferă o listă completă de pagini din start
- Include metadate despre importanța și prospețimea paginilor
- Evită crawling-ul paginilor inutile
- Reduce încărcarea serverului
Dar pentru acest capitol, ne vom concentra pe crawling-ul bazat pe link-uri folosind Crawlee pentru a construi un crawler pentru un site e-commerce multi-pagină. Crawlee gestionează multe dintre complexitățile web crawling-ului pentru noi, inclusiv:
- Gestionarea automată a cozii și deduplicarea URL-urilor
- Rate limiting încorporat și logica de retry
- Gestionarea configurabilă a request-urilor și routing-ul
- Stocarea și exportul datelor
Structura site-ului pe care o vom crawla arată astfel:
Homepage
├── Categorie: Electronică
│ ├── Telefoane
│ ├── Laptopuri
│ └── Accesorii
├── Categorie: Îmbrăcăminte
│ ├── Bărbați
│ └── Femei
└── Produse recomandate
Fiecare pagină de produs are layout-uri diferite în funcție de categorie, dar trebuie să extragem informații consistente:
// Exemplu structură de date pe care vrem să o construim
interface ProductData {
name: string;
price: number;
rating: { score: number, count: number };
features: string[];
status: string; // În stoc, Epuizat, etc.
}
interface ResultData {
categories: {
electronics: {
phones: ProductData[];
laptops: ProductData[];
accessories: ProductData[];
};
clothing: {
mens: {
shirts: ProductData[];
pants: ProductData[];
};
womens: {
dresses: ProductData[];
tops: ProductData[];
};
};
};
featured_products: FeaturedProduct[];
}
Concepte cheie de crawling cu Crawlee
- Gestionarea cozii de request-uri
Crawlee gestionează coada automat, dar iată cum o configurăm:
import { CheerioCrawler } from 'crawlee';
const crawler = new CheerioCrawler({
// Gestionează fiecare request
async requestHandler({ $, request, enqueueLinks }) {
// Procesează pagina
const data = extractPageData($);
// Adaugă automat în coadă URL-uri noi găsite pe pagină
await enqueueLinks({
selector: 'a',
baseUrl: request.loadedUrl,
});
},
// Limitează request-urile concurente
maxConcurrency: 10,
});
- Gestionarea URL-urilor
Crawlee oferă gestionarea și normalizarea încorporată a URL-urilor:
await crawler.run([startUrl]);
// Sau cu mai multă configurare:
await crawler.addRequests([{
url: startUrl,
userData: {
label: 'start',
},
}]);
- Gestionarea rutelor
Direcționează URL-uri diferite către handler-e specifice:
const crawler = new CheerioCrawler({
async requestHandler({ $, request }) {
const { label } = request.userData;
switch (label) {
case 'category':
return handleCategory($);
case 'product':
return handleProduct($);
default:
return handleHomepage($);
}
},
});
- Colectarea datelor
Crawlee oferă stocare încorporată pentru datele colectate:
const crawler = new CheerioCrawler({
async requestHandler({ $, pushData }) {
const productData = extractProduct($);
await pushData(productData);
},
});
Cele mai bune practici pentru web crawling
În timp ce Crawlee gestionează multe preocupări de nivel scăzut, ar trebui să iei în considerare totuși:
-
Configurația
- Setează rate limit-uri adecvate
- Configurează strategii de retry
- Setează string-uri de user-agent semnificative
-
Gestionarea erorilor
- Folosește gestionarea erorilor încorporată a Crawlee
- Implementează callback-uri de eroare personalizate
- Loghează informații de diagnostic semnificative
-
Organizarea datelor
- Structurează datele consistent
- Folosește etichete de request pentru routing
- Valorifică funcționalitățile de dataset ale Crawlee
-
Gestionarea resurselor
- Configurează maxConcurrency adecvat
- Folosește maxRequestsPerCrawl când este necesar
- Monitorizează utilizarea memoriei
Provocarea
Sarcina ta este să construiești un crawler bazat pe Crawlee care:
- Începe de pe homepage și descoperă toate categoriile de produse
- Vizitează fiecare pagină de categorie și subcategorie
- Extrage informații despre produse din fiecare listing
- Organizează datele într-un format structurat
- Gestionează produsele care apar în multiple locuri (ex. recomandate și categorie)
Site-ul conține aproximativ 25-30 de produse în categorii diferite, cu layout-uri și structuri de informații variate. Crawler-ul tău ar trebui să producă un dataset cuprinzător care menține relația ierarhică între categorii și produse.
Testarea soluției tale
Testează pentru:
- Completitudine: Ai găsit toate produsele?
- Acuratețe: Sunt datele extrase corecte?
- Structură: Sunt datele organizate corespunzător?
- Eficiență: Câte request-uri ai făcut?
Exemplul rezolvat în _solved/chapter6/
oferă o implementare de referință folosind Crawlee. Studiază-l pentru a înțelege cum să valorifici funcționalitățile bibliotecii pentru crawling multi-pagină eficient și organizarea datelor.
Crawling fericit!