Conversation
A 5xx or a network error while fetching robots.txt was parsed as an empty (allow-all) body and cached for the session, so a site whose robots.txt was temporarily 500ing got crawled as if unrestricted — the exact failure robots handling should prevent. Now the fetch uses get_raw so the real status code is visible, and a helper splits handling by class per RFC 9309 / Googlebot: 2xx uses the rules, 4xx is allow-all (both cacheable), 5xx (and network errors) fail closed with a disallow-all parser that is NOT cached, so the next request re-fetches. Sync and async share the same decision helper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release 1.5.6. Bundles the robots.txt server-error fix (#152) with two
contributor fixes already merged to main (#151, #150), and bumps the version
across all sites.
Changes
Fixed
5xx(or a connectionerror / timeout) while fetching
robots.txtwas parsed as an empty allow-allbody and cached for the session, so a site whose
robots.txtwas temporarily500ing got crawled as if unrestricted. The fetch now uses
get_rawso the realstatus code is visible, and handling is split by class per RFC 9309 / Googlebot:
2xxuses the rules,4xxis allow-all (both cacheable), and5xx/ networkerrors fail closed with a disallow-all parser that is not cached, so the
next request re-fetches. Sync and async share one decision helper.
offset=/start=URLs,find_next_page_urlinfers the step from the gapsbetween the page links (e.g.
0/20/40/60→+20) instead of+1, whichsilently under-collected on offset-paginated sites.
page/pURLs stilladvance by 1.
ScrapeResult.save()creates parent directories (save() fails when the target directory does not exist #150). Saving to a pathwhose directory does not exist (e.g.
out/nested/data.json) now creates thetree instead of raising
FileNotFoundError.Chore
pyproject.toml,__init__.py, andserver.json; updateCHANGELOG.
Testing
ruff checkandruff format --check: clean.code and pass after, confirming the fix is exercised.
Closes #152.