MCPcopy Create free account
hub / github.com/apify/crawlee-python / _fetch_and_process_sitemap

Function _fetch_and_process_sitemap

src/crawlee/_utils/sitemap.py:338–418  ·  view source on GitHub ↗

Fetch a sitemap from a URL and process its content.

(
    http_client: HttpClient,
    source: SitemapSource,
    depth: int,
    visited_sitemap_urls: set[str],
    sources: list[SitemapSource],
    retries_left: int,
    *,
    proxy_info: ProxyInfo | None = None,
    timeout: timedelta | None = None,
    emit_nested_sitemaps: bool,
    enqueue_strategy: EnqueueStrategy,
)

Source from the content-addressed store, hash-verified

336
337
338async def _fetch_and_process_sitemap(
339 http_client: HttpClient,
340 source: SitemapSource,
341 depth: int,
342 visited_sitemap_urls: set[str],
343 sources: list[SitemapSource],
344 retries_left: int,
345 *,
346 proxy_info: ProxyInfo | None = None,
347 timeout: timedelta | None = None,
348 emit_nested_sitemaps: bool,
349 enqueue_strategy: EnqueueStrategy,
350) -> AsyncGenerator[SitemapUrl | NestedSitemap, None]:
351 """Fetch a sitemap from a URL and process its content."""
352 if 'url' not in source:
353 return
354
355 sitemap_url = source['url']
356
357 while retries_left > 0:
358 retries_left -= 1
359 try:
360 async with http_client.stream(
361 sitemap_url, method='GET', headers=SITEMAP_HEADERS, proxy_info=proxy_info, timeout=timeout
362 ) as response:
363 # Determine content type and compression
364 content_type = response.headers.get('content-type', '')
365
366 decoder = getincrementaldecoder('utf-8')(errors='replace')
367
368 # Create appropriate parser
369 parser = _get_parser(content_type, sitemap_url)
370 decompressor = None
371 try:
372 # Process chunks as they arrive
373 first_chunk = True
374 async for raw_chunk in response.read_stream():
375 # Check if the first chunk is a valid gzip header
376 if first_chunk and raw_chunk.startswith(b'\x1f\x8b'):
377 decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16)
378 first_chunk = False
379
380 chunk = decompressor.decompress(raw_chunk) if decompressor else raw_chunk
381 text_chunk = decoder.decode(chunk)
382 async for item in parser.process_chunk(text_chunk):
383 async for result in _process_sitemap_item(
384 item,
385 source,
386 depth,
387 visited_sitemap_urls,
388 sources,
389 emit_nested_sitemaps=emit_nested_sitemaps,
390 enqueue_strategy=enqueue_strategy,
391 ):
392 if result:
393 yield result
394
395 # Process any remaining content

Callers 1

parse_sitemapFunction · 0.85

Calls 7

_get_parserFunction · 0.85
_process_sitemap_itemFunction · 0.85
streamMethod · 0.45
read_streamMethod · 0.45
process_chunkMethod · 0.45
flushMethod · 0.45
closeMethod · 0.45

Tested by

no test coverage detected