--- title: "Python Scraping Patterns: 15 Real Problems, 15 Working Solutions" author: "ZyVOP" published: "2026-07-23T14:06:15.319Z" updated: "2026-08-25T12:00:00.844Z" url: "https://zyvop.com/python-scraping-patterns-15-real-problems-15-working-solutions-fej2u" canonical: "https://zyvop.com/python-scraping-patterns-15-real-problems-15-working-solutions-fej2u" tags: ["web scraping edge cases python","web scraping patterns cookbook","python scraper not working fix","common web scraping problems python","python scraping troubleshooting"] --- # Python Scraping Patterns: 15 Real Problems, 15 Working Solutions 15 real Python scraping problems and their working solutions — lazy loading, infinite scroll, login walls, JavaScript data, CAPTCHAs, rate limits, and more. Copy-paste ready code. ![Cover image]() Every scraping project hits the same walls. You write what looks like correct code, point it at a real website, and something doesn't work. The element isn't there. The data is missing. The response is empty. The selector returns `None`. This is a reference guide. Fifteen patterns you will hit. Fifteen solutions that work. Bookmark it, come back when you're stuck. * * * ## Pattern 1: The Element You Need Doesn't Exist in BeautifulSoup **The problem:** `soup.select_one(".price")` returns `None` even though the element is clearly visible in your browser. **Why it happens:** The page uses JavaScript to render the content. BeautifulSoup parses the _initial HTML response_ from the server — before JavaScript runs. Any element injected by JavaScript after page load is invisible to BeautifulSoup. **The signal:** Open the page, right-click the element, click "View Page Source." If the element isn't in the raw source, it's JavaScript-rendered. **Solution A — Use Playwright to get the rendered HTML:** ```python from playwright.sync_api import sync_playwright from bs4 import BeautifulSoup def get_rendered_html(url: str) -> str: """Fetch fully rendered HTML after JavaScript executes.""" with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(url, wait_until="networkidle") # Wait for JS to finish html = page.content() # This is the post-JS DOM browser.close() return html html = get_rendered_html("https://js-heavy-site.com/products") soup = BeautifulSoup(html, "lxml") price = soup.select_one(".price") # Now it finds it ``` **Solution B — Find the XHR/fetch call that loads the data (faster, cheaper):** 1. Open DevTools → Network tab → filter by XHR/Fetch 2. Reload the page 3. Find the API call that returns JSON with your data 4. Call that endpoint directly — no browser needed ```python import httpx # Instead of scraping the rendered page, call the API the page uses r = httpx.get( "https://site.com/api/products?category=electronics", headers={"User-Agent": "Mozilla/5.0 Chrome/120"} ) data = r.json() # Clean structured data, no parsing needed ``` **When to use B over A:** Always try B first. It's 10–50x faster and requires no browser. * * * ## Pattern 2: The Data Is in a `