TL;DR: Using JavaScript with Scrapy does not always require a browser. First inspect the raw response, network requests, and embedded page state; add scrapy-playwright only when the target data truly depends on browser execution, then control waits, interactions, cleanup, and concurrency deliberately.
Using JavaScript with Scrapy means adding browser execution for pages whose required data appears only after client-side code runs. The practical goal is not to render every page, but to identify the cheapest reliable path to the data: raw HTML, a JSON request, an embedded JavaScript object, or, only when necessary, a browser-built DOM.
That distinction matters because Scrapy's downloader receives the server's response, while Chrome or Firefox may make additional requests and mutate the document afterward. A React, Vue, or Angular page can therefore look complete in DevTools even though response.text contains little more than an application shell.
This guide starts with a browser-last diagnosis, then builds a focused scrapy-playwright workflow for the requests that genuinely need execution. You will also see how to use condition-based waits, handle clicks and session state, compare rendering options, and keep dynamic spiders stable in production. The result is a workflow that preserves Scrapy's efficient HTTP pipeline wherever possible without pretending that every modern site can be scraped from static markup alone.
Static-page basics come first, and our Python web scraping guide is the place that workflow builds on.




