Python Notes
Complete guide to web scraping with Python using requests, BeautifulSoup4, lxml, handling pagination, scraping APIs, and best practices with Hindi explanations.
Introduction
Web Scraping is automatically extracting data from websites. Combining requests (HTTP requests) and BeautifulSoup4 (HTML parsing) in Python creates a powerful scraping toolkit.
pip install requests beautifulsoup4 lxml2. BeautifulSoup4 — HTML Parsing
3. Navigating HTML Tree
4. CSS Selectors
📝 Hindi Explanation
CSS Selectors are the most powerful way to find HTML elements: -tag— element type se -.class— class se -#id— ID se -[attr='val']— attribute se -parent > child— direct child -a b— descendant (any level) -:nth-child(n)— position se
5. Real-World Scraping
6. Handling Pagination
7. Scraping JSON APIs
8. Scraping with Sessions and Cookies
9. Best Practices and Ethics
Summary
| Tool | Use Case |
|---|---|
requests | HTTP requests (GET/POST) |
BeautifulSoup4 | HTML parsing, element extraction |
lxml | Fast HTML/XML parser (BS4 backend) |
.find() | First matching element |
.find_all() | All matching elements |
.select() | CSS selector |
.select_one() | Single CSS selector match |
session.get() | Session with persistent headers/cookies |
Ethics: Always check robots.txt, add delays between requests, don't overload servers, cache results, and use official APIs when available. Scraping is a tool — use it responsibly!Output Examples 📋
Section 1 Output — HTTP Requests
Status code: 200
Content type: application/json
Response size: 498 bytes
{"headers": {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...", "Accept": "text/html,application/xhtml+xml..."}}
URL with params: https://httpbin.org/get?q=python+scraping&lang=en&page=1Section 2 Output — BeautifulSoup4 HTML Parsing
Title text: Learn Python Web Scraping Title id: main-title Intro: Python se web scraping seekho. Topic 1: BeautifulSoup Topic 2: Requests Topic 3: Selenium Link: Python Docs -> https://example.com/python Link: BS4 Docs -> https://example.com/bs4 First link: Python Docs
Section 3 Output — Navigating HTML Tree
Parent: div
Child: h2 — Python Tutorial
Child: span — WoHoTech
Child: time — June 12, 2026
All text: Python Tutorial WoHoTech June 12, 2026 First paragraph with bold text. Second paragraph with a link. python, tutorial, scraping
datetime attr: 2026-06-12
All attrs: {'datetime': '2026-06-12'}
Bold text: bold textSection 4 Output — CSS Selectors
=== CSS Selectors ===
All prices: ['₹75,000', '₹25,000', '₹35,000']
Table id: products
Names: ['Laptop', 'Phone', 'Tablet']
In stock items: 2
First row: Laptop
Product ID 2: Phone
In stock count: 2
Products table:
{'id': '1', 'name': 'Laptop', 'price': '₹75,000', 'status': 'In Stock'}
{'id': '2', 'name': 'Phone', 'price': '₹25,000', 'status': 'Out of Stock'}
{'id': '3', 'name': 'Tablet', 'price': '₹35,000', 'status': 'In Stock'}Section 5 Output — Real-World Scraping
Heading: Herman Melville - Moby Dick
Section 6 Output — Handling Pagination
Scraping page 1... Scraping page 2... Scraping page 3... No items on page 3 — stopping
Section 7 Output — JSON APIs
Post 1: sunt aut facere repellat provident occaecati exc Post 2: qui est esse Post 3: ea molestias quasi exercitationem repellat qui i Post 4: eum et est occaecati Post 5: nesciunt quas odio User: Leanne Graham Email: Sincere@april.biz City: Gwenborough Company: Romaguera-Crona
Section 8 Output — Sessions and Cookies
Cookies: {'session_id': 'abc123'}Section 9 Output — Best Practices
Scraping allowed!
⚠️ Common Mistakes
❌ Mistake 1: User-Agent Header Na Bhejana
# ❌ Wrong — many sites block requests without User-Agent
response = requests.get("https://example.com")
# ✅ Right — always send proper User-Agent
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
response = requests.get("https://example.com", headers=headers)🔑 Tip: Without a User-Agent, many websites will return 403 Forbidden or empty responses.
❌ Mistake 2: Error Handling Skip Karna
# ❌ Wrong — will crash if site is down!
response = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "lxml")
# ✅ Right — handle errors gracefully
try:
response = requests.get("https://example.com", timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, "lxml")
except requests.RequestException as e:
print(f"Error: {e}")🔑 Tip: Network requests can always fail — always use try/except and set a timeout.
❌ Mistake 3: Rate Limiting Na Karna
# ❌ Wrong — server pe attack jaisa lagega
for url in urls:
response = requests.get(url)
# ✅ Right — requests ke beech delay rakho
import time
for url in urls:
response = requests.get(url)
time.sleep(1) # 1 second ka gap🔑 Tip: Without delays, the server will be overloaded and your IP will be banned.
❌ Mistake 4: Hardcoded Selectors Use Karna
# ❌ Wrong — ek selector change hone pe pure code break
title = soup.select_one("body > div:nth-child(3) > div > h2")
# ✅ Right — robust selectors use karo
title = soup.select_one("h2.article-title")🔑 Tip: Use class-based or ID-based selectors, not position-based ones. Websites change their HTML structure frequently.
❌ Mistake 5: .text vs .string Ka Confusion
# ❌ Wrong — .string returns None if element has children
content = soup.find("div").string # None if nested elements
# ✅ Right — .text ya .get_text() use karo
content = soup.find("div").get_text(strip=True)🔑 Tip:.stringonly works when an element contains a single NavigableString..get_text()is more reliable.
❌ Mistake 6: robots.txt Check Na Karna
# ❌ Wrong — blindly scraping without permission check
data = requests.get("https://example.com/private-data")
# ✅ Right — check robots.txt first
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url("https://example.com/robots.txt")
rp.read()
if rp.can_fetch("*", "https://example.com/private-data"):
data = requests.get("https://example.com/private-data")🔑 Tip: To avoid legal issues, always respect robots.txt. Some websites can take legal action against scraping.
❌ Mistake 7: Not Validating Data
# ❌ Wrong — element None ho sakta hai
price = soup.find("span", class_="price").text # AttributeError!
# ✅ Right — check for None first
price_elem = soup.find("span", class_="price")
price = price_elem.text if price_elem else "N/A"🔑 Tip: Website structure can change or elements may be missing — always check for None.
✅ Key Takeaways
- 🔹 requests + BeautifulSoup4 = Python's most popular web scraping combo —
requestshandles HTTP,BeautifulSoup4parses HTML - 🔹 Always set a User-Agent header — many websites block requests or return incomplete data without one
- 🔹
find()vsfind_all()—find()returns the first match (single element),find_all()returns a list (multiple elements) - 🔹 CSS Selectors (
select()) are more powerful for complex queries — handles class, id, attributes, and nested elements - 🔹 Rate Limiting is essential — use
time.sleep()between requests. A 1-2 second gap is respectful scraping - 🔹 Use Session when cookies/login need to be maintained —
requests.Session()persists headers and cookies across requests - 🔹 Always check robots.txt before starting to scrape — it shows the website owner's permissions/restrictions
- 🔹 Error handling (try/except) is mandatory — network failures, timeouts, 404s — anything can happen at runtime
- 🔹 Use lxml parser for speed — it's ~10x faster than the default
html.parseron large HTML documents - 🔹 Prefer JSON APIs over HTML scraping — if the website has an API available, use it directly; it's more stable and faster
❓ FAQ
Q1: Web Scraping legal hai ya illegal? 🤔
Answer: Web scraping itself is not illegal, BUT — violating a website's Terms of Service, scraping copyrighted content, or collecting personal data without consent can have legal consequences. Always check robots.txt and ToS.
Q2: BeautifulSoup vs Scrapy — kaunsa use karein? 🛠️
Answer: BeautifulSoup is best for simple scripts — when you need to scrape one or two pages or do quick data extraction. Scrapy is a full-featured framework for large-scale projects — built-in pipeline, middleware, concurrent requests, data export.
Q3: Website has blocked my IP — now what? 🚫
Answer: When IP-blocked: (1) Increase rate limiting (more delay), (2) Use rotating proxies, (3) Implement User-Agent rotation, (4) Use sessions/cookies properly, (5) Consider switching to a headless browser. Prevention: always add delays and don't hammer the server.
Q4: How to scrape JavaScript-rendered pages? ⚡
Answer: BeautifulSoup can only parse static HTML. For JS-rendered content: (1) Selenium — full browser automation, (2) Playwright — modern alternative, faster than Selenium, (3) requests-html — lightweight with JS rendering support, (4) Check if the site has a REST API returning JSON directly.
Q5: How to prevent infinite loops when handling pagination? 🔄
Answer: (1) Set a max_pages limit, (2) Check if the next page button exists or is disabled, (3) Track already-visited URLs, (4) Check for empty response/no new data, (5) Compare current page content with previous — if identical, stop.
Q6: Where should you store scraped data? 💾
Answer: Depends on data size and use-case: (1) CSV/JSON files — for small data and quick analysis, (2) SQLite — for medium data and local storage, (3) PostgreSQL/MongoDB — for large-scale production with querying needs, (4) Cloud storage (S3) — for raw data archival.
Q7: lxml vs html.parser — kaunsa parser better hai? 🏎️
Answer: lxml is significantly faster (C-based) and handles broken HTML leniently. html.parser is Python built-in — no extra installation required, good for simple tasks. For production scraping with large pages, always use lxml.
Q8: How to keep API keys and credentials secure in code? 🔐
Answer: (1) Use environment variables — os.environ.get("API_KEY"), (2) Use .env file + python-dotenv library, (3) Never commit credentials to code or version control, (4) Use secret managers (AWS Secrets Manager, HashiCorp Vault) in production.
🎯 Interview Questions
Q1: What is Web Scraping and what are its key components?
Answer: Web Scraping is an automated technique for programmatically extracting data from websites. Key components: (1) HTTP Client (requests) — sends requests and receives responses, (2) HTML Parser (BeautifulSoup/lxml) — parses HTML structure, (3) Data Extraction — locates and pulls specific data, (4) Storage — saves to file/database.
Q2: What is the difference between find() and find_all()?
Answer: find() returns the first matching element (Tag object or None), while find_all() returns all matching elements as a list (empty list if none found). find() is essentially find_all(limit=1)[0]. Use find() for unique elements (IDs) and find_all() for collections (list items, table rows).
Q3: What are the advantages of using requests.Session()?
Answer: (1) Cookies persist across requests — login state is maintained, (2) Headers are reused — no need to set them on every request, (3) Connection pooling — TCP connections are reused for performance, (4) Simplified auth — set once, apply everywhere.
Q4: What is the fundamental difference between Scrapy and BeautifulSoup?
Answer: BeautifulSoup is only an HTML/XML parser — it doesn't make HTTP requests or store data by itself. Scrapy is a complete web scraping framework — built-in request scheduling, data pipelines, middleware, caching, rate limiting, concurrent requests, and export formats.
Q5: What are anti-scraping mechanisms and how do you deal with them?
Answer: Common anti-scraping techniques: (1) IP blocking — solution: rotating proxies, (2) CAPTCHA — solution: CAPTCHA solving services or avoid triggering them, (3) JavaScript rendering — solution: headless browsers, (4) Rate limiting — solution: delays and request throttling, (5) Honeypot traps — solution: check link visibility before following.
Q6: What is the difference between XPath and CSS Selectors?
Answer: CSS Selectors: simpler syntax, familiar to web developers, forward-only navigation (parent to child). XPath: more powerful, bidirectional navigation (can go from child to parent), supports text-based selection. CSS is sufficient for 90% of cases; use XPath when you need parent traversal or complex text conditions.
Q7: What is the best approach for error handling in Web Scraping?
Answer: Multi-layer error handling: (1) Network level — try/except requests.RequestException, set timeout, (2) HTTP level — response.raise_for_status() to catch 4xx/5xx, (3) Parse level — check for None before accessing attributes, (4) Data level — validate extracted data types and formats. Add retries with exponential backoff for transient errors.
Q8: What is robots.txt and what is its importance in scraping?
Answer: robots.txt is a standard file at a website's root (e.g., https://example.com/robots.txt) that tells web crawlers which paths are allowed or disallowed for scraping. Respecting it is ethical practice and can protect you from legal issues. Use urllib.robotparser to programmatically check permissions.
Q9: How do you design a data pipeline for a large-scale scraping project?
Answer: Production pipeline: (1) URL Queue — store URLs in Redis/RabbitMQ, (2) Fetcher — concurrent HTTP requests with rate limiting, (3) Parser — extract structured data from HTML, (4) Validator — check data quality and completeness, (5) Storage — write to database/file with deduplication, (6) Monitor — track success rates, errors, and performance metrics.
Q10: What are the best tools for scraping dynamic websites (SPAs)?
Answer: For Single Page Applications (React, Angular, Vue): (1) Selenium — most popular, full browser automation, but slow, (2) Playwright — Microsoft's modern alternative, supports Chromium/Firefox/WebKit, faster than Selenium, (3) Puppeteer — Google's Node.js solution, Chrome-only but very fast, (4) Splash — lightweight headless browser as a service (with Scrapy), (5) requests-html — simple JS rendering for basic SPAs.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Web Scraping with Python.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Python Master Course topic.
Search Terms
python-master-course, python master course, python, master, course, automation, web, scraping
Related Python Master Course Topics