Repository navigation
Conversation
…dified` - Add `conditional_requests` and `conditional_requests_dir` to `Spider`. The validators of each processed response are saved per request fingerprint and sent back as `If-None-Match` / `If-Modified-Since` on the next run - A `304 Not Modified` answer skips the request's callback, calls the new `on_not_modified()` hook, counts in `not_modified_count`, and is treated as healthy by AutoThrottle - Validators are saved only after a 2xx callback finished without raising, and only for GET/HEAD requests that don't set their own conditional headers - `SessionManager.fetch()` takes per-fetch `headers` that aren't stored on the request, so `response.follow()` never inherits the validators - Disabled while `development_mode` is on, so the response cache keeps working exactly as before - Added tests (including one against a real server through `FetcherSession`) and documentation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…delay The delay after a fast fake fetch depended on its latency, which made the test flaky on slow machines. Recording the `ok` flag the engine reports is exact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Base:
dev· Branch:feat/conditional-requests(2 commits,be5769c,9260867)Why
Spiders that run on a schedule, such as one that checks a set of feeds every few minutes, mostly re-download pages that haven't changed. Most servers support conditional requests, but nothing in
scrapling/spiders/sendsIf-None-Match/If-Modified-Sinceor understands a304. Doing it by hand in a spider is awkward: headers set on a request are inherited byresponse.follow(), and the validators have to be kept somewhere between runs.What changes
Spiderattributesconditional_requests = Falseandconditional_requests_dir = None(default.scrapling_validators/{name}/, mirroring.scrapling_cache/).ConditionalRequestManager(spiders/conditional.py) with the same on-disk layout and atomic writes asResponseCacheManager: one small JSON file per request fingerprint holding theETag/Last-Modifiedvalues.If-None-Match/If-Modified-Since.304answer to a conditional request skips the callback and calls a newSpider.on_not_modified(request, response)hook (a no-op by default). It counts in a newnot_modified_countstat, and AutoThrottle records it as healthy. Without that, AutoThrottle would back off on every unchanged page.2xxresponse's callback finished without raising, so a page that failed (or was blocked) is downloaded in full next time. A response with no validators deletes the old entry.SessionManager.fetch()takes optional per-fetchheadersthat are merged into a copy of the kwargs. The request is never modified, soresponse.follow()never inherits the validators. Browser sessions readextra_headers, so they ignore these and simply fetch normally.development_modeis on. A cache miss needs the full body to cache, and a304would leave nothing to replay.cache.pybehaves exactly as before.Tests
22 new cases in
tests/spiders/test_conditional.py. Most drive a realSpideragainst a fake site that implements RFC 9110 conditional logic, plus one end-to-end case through the defaultFetcherSessionagainstpytest-httpbin's/etag/{etag}. They cover:the 304 skip and hook, changed pages,
Last-Modifiedalonefailed callbacks and blocked responses not being remembered
followed requests not inheriting validators, and shared header dicts staying untouched
user-set validators, POST requests, disabled-by-default
the AutoThrottle health flag, and development mode replaying from the cache unchanged
pytest tests/spiders -m "not browser": 528 passed (506 ondev)ruff,mypy scrapling/,vermin -t=3.10-,bandit: clean.pyright: no new errors.Notes
CrawlerEngine._run_callbacks. Whichever lands second needs a small rebase: keepreturn Falsein theexcept, then the seen-storeadd, thenreturn True. I checked that combination locally: 577 passed._run_callbacksnow returnsbool(whether the callback finished without raising). It's private.docs/spiders/advanced.md(English only).AI disclosure
This PR was written primarily by Claude Code, Anthropic's coding agent: the code, the tests, the docs and this description. I asked for these changes while building a news-monitoring project on top of Scrapling's spiders, where the gaps came up, and I chose to submit them. The test results above come from local runs on Windows with Python 3.12. Happy to make any changes.
🤖 Generated with Claude Code