roach-php/laravel
Laravel integration for Roach PHP, a Scrapy-inspired web scraping framework. Run spiders as Artisan commands, configure crawlers and pipelines, and use Laravel's container, config, queues, and scheduling to build maintainable scrapers inside your app.
Architecture fit: Roach PHP for Laravel is a scraping toolkit wrapped in Laravel-native conventions — service container bindings, publishable config, Artisan commands for spider scaffolding and execution, and scheduler integration. Architecturally it slots into a Laravel app as a bounded capability: define Spider classes that encapsulate a crawl (entry URLs, item pipeline, parse/parseItem callbacks), dispatch from a command or queued job, persist results via Laravel's normal channels. This is a better fit than ad-hoc Guzzle+Regex scripts because it gives you a reusable, testable unit of scraping logic with lifecycle hooks. It is not, however, a scraping platform: no headless browser, no proxy pool, no CAPTCHA handling, no hosted scheduling. Teams expecting "Scrapy-in-Laravel" should calibrate expectations — Roach is HTTP-client-level scraping with a clean abstraction.
Integration feasibility: High for an existing Laravel codebase on a supported version. Installation is composer require roach-php/laravel, publishing config, and scaffolding a spider. No database migrations, no middleware, no route surface. The 3.2.0 release (March 2025) adds Laravel 12 and PHP 8.4 support, so it is viable for teams on current stacks. The friction is not technical integration but governance: legal/ToS review of target sites, robots.txt compliance, and rate-limit policy must be decided before the first spider is written, not after.
Technical risk: Moderate, concentrated in the problem domain rather than the package. (1) Scraper fragility — selectors and page structures on target sites drift; every spider is a maintenance liability. (2) Anti-bot defenses — Cloudflare, DataDome, Akamai, 403/429 responses, and CAPTCHAs are the leading cause of production scrape failures; Roach alone does not address them. (3) Vendor concentration — a 262-star package with a small contributor base is not a durable dependency in the way laravel/framework is; a maintainer step-away would leave you on a fork. (4) Freshness of 3.2.0 — Laravel 12/PHP 8.4 support landed recently; regression testing on your stack is warranted. (5) No JS rendering — SPA targets need a separate headless-browser path.
Key questions:
composer.lock pinning, contract with an internal owner)?Stack fit: Strong for Laravel 10/11/12 applications on PHP 8.2+. It coexists cleanly with existing container bindings, queues, scheduler, and logging, which is the whole point of the package relative to raw Roach. It does not require changes to auth, routing, or persistence. It does introduce outbound HTTP as a first-class runtime dependency, so egress rules, DNS allowlists, and secrets (API keys, proxies) need to be provisioned in every environment.
Migration path: If replacing ad-hoc scraping (Guzzle + DomCrawler in commands, or a legacy Python/Scrapy service), start by wrapping one existing target as a Roach spider, keeping the old path behind a feature flag until parity is confirmed by a shadow-run that diffs outputs. Do not attempt a big-bang port — scrapers fail in site-specific, not framework-specific, ways, and per-target cutover isolates that risk. If greenfield, ship a single POC spider against a non-critical target before committing to the pattern.
Compatibility: Pin the package to ^3.2 in composer.json — earlier 3.x will not resolve against laravel/framework:^12. Verify PHP 8.4 deprecation noise from transitive dependencies early (failOnDeprecation=true in CI). Confirm the queue driver supports the concurrency model you intend (Redis/Database over sync for anything recurring). Check that existing Guzzle middleware (auth, logging, retry) doesn't conflict with Roach's HTTP client setup — Roach exposes its own client config, so the two rarely conflict, but audit rather than assume. Config-cache correctness matters: new keys introduced by a package bump stay null until config:cache runs again.
Sequencing:
Retry-After), storage destination, retention.Maintenance: This is the dominant cost and it is not the package — it is the spiders. Plan a standing maintenance allocation per target (selectors, pagination, auth flows, anti-bot responses) and treat package upgrades as the smaller line item. Track the package's release cadence and its compatibility window against Laravel's support policy; 3.2.0 is current, but a small project's next release is not guaranteed on Laravel 13's timeline. Mitigate by isolating Roach behind an internal adapter (a thin Scraper service + Spider base class) so a fork or replacement is a single-file change rather than a call-site sweep.
Support: MIT, community-supported, no vendor SLA. Internal ownership must be explicit — one named engineer accountable for upgrade, incident response, and selector remediation. Security posture: scraping packages execute remote-fetched content through parsers (Guzzle, Symfony DomCrawler); keep dependencies patched and treat scraped HTML as untrusted input. Establish a quarterly dependency review and a documented fork-and-patch procedure in case the upstream goes quiet.
Scaling: Scales on the usual Laravel axes — queue workers, horizontal app instances — but the real ceilings are external: target-site rate limits, IP reputation, and per-target concurrency caps. Rate limiting must be shared state (Redis token bucket), not per-worker, or you will exceed politeness budgets under load. Storage planning matters as much as crawl planning: item volume, dedup, schema evolution, and retention need explicit design before month two. If targets are JS-heavy or heavily defended, the roadmap forks toward headless-browser or managed-scraping spend — call that out early rather than discovering it during a crawl outage.
Failure modes:
Ramp-up: Low-to-moderate. A comfortable Laravel engineer can produce a working spider in a day using the Artisan scaffolding and published config. Two to three days gets them to a defensible pattern (pipelines, retries, tests). The genuinely slow part is not the package API — it is the operational discipline: polite crawling, robust parsing, observability on scraped output, and an upgrade/fork posture for a small-community dependency. Budget one engineer-half for the first two targets and a written internal standard before scaling to many.
How can I help you explore Laravel packages today?