Python Web Scraping: What Actually Works A developer's practical guide to Python web scraping in 2026 warns that basic techniques like `time.sleep()` lead to blocks, recommending `httpx` with `selectolax` for static pages, Playwright for client-side rendering, and checking the Network tab for JSON APIs as a cheat code. The guide advises using residential proxies and adaptive pacing with a custom `AdaptiveLimiter` class to beat advanced bot detection systems like DataDome and PerimeterX. Python Web Scraping: What Actually Works time.sleep on your code is a great way to get blocked in 2026. Modern sites aren't just looking at your headers; they're fingerprinting your TLS handshake and tracking your mouse movements like some digital private eye. If you're still scraping like it's 2018, you're basically just donating your IP addresses to a blacklist.My current real-world AI workflow for data extraction focuses on picking the right tool for the target, rather than just defaulting to whatever tutorial I found on Medium. Tooling Selection Stop using Playwright or Selenium for everything. Launching a full browser is a resource hog and usually overkill. Static/Server-Rendered Pages: I use httpx with selectolax . Selectolax is C-backed and destroys BeautifulSoup in terms of speed on large pages, while httpx handles HTTP/2 and async without the drama. python import httpx from selectolax.parser import HTMLParser def scrape static url : resp = httpx.get url, headers={"User-Agent": "Mozilla/5.0"} tree = HTMLParser resp.text for node in tree.css ".listing" : print node.text Client-Side Rendering: Playwright is the only sane choice here. It's faster than Selenium and the auto-waiting logic means I spend less time debugging flaky selectors. python from playwright.sync api import sync playwright def scrape with playwright url : with sync playwright as p: browser = p.chromium.launch headless=True page = browser.new page page.goto url, wait until="networkidle" results = item.query selector "h2" .text content for item in page.query selector all ".job-item" browser.close return results The "Cheat Code": Always check the Network tab in DevTools first. Half the time, the site is just hitting a JSON API. If you can find that endpoint, you can skip the HTML parsing nightmare entirely. url = "https://www.freelancer.com/api/projects/0.1/projects/active/?query=python" data = httpx.get url .json Beating Bot Detection When you're up against DataDome or PerimeterX, a random User-Agent is basically a placebo. They know you're a bot because your TLS fingerprint screams "Python library" and your IP comes from a datacenter. Residential proxies are non-negotiable for high-tier targets. Pair those with adaptive pacing so you don't look like a clockwork robot: python import time class AdaptiveLimiter: def init self, min delay=1.0, max delay=5.0 : self.min delay = min delay self.max delay = max delay self.current delay = min delay def wait self : time.sleep self.current delay def on success self : self.current delay = max self.min delay, self.current delay 0.9 def on block self : self.current delay = min self.max delay, self.current delay 1.5 The logic is simple: if you get blocked, back off. If it's working, gradually speed up. It's a practical tutorial in not getting banned. Next Claude Code: Managing Multi-Repo Workspaces → /en/threads/3217/