Knowledge / Artificial Intelligence and Data Science / Data collection and web scraping

Data collection and web scraping

Artificial Intelligence and Data Science (B.E./B.Tech) · Programming and data · free study notes for exams, placements and interviews

In short

Data collection is the step that turns a real-world question into rows a program can read; web scraping is the automated extraction of data from web pages when no file or API is offered. Every AI/DS pipeline starts here - a model trained on badly collected data cannot be rescued by better algorithms. University syllabi examine collection methods, sampling, HTTP, HTML parsing and the ethics/legal frame; placement tests ask for requests + BeautifulSoup code, API pagination logic and rate-limit handling. Indian employers who hire for this include Flipkart, Zomato, Swiggy, Paytm, PhonePe, Jio, Dream11, Zepto, Tracxn, Mu Sigma and almost every pricing-intelligence or lending-analytics firm; it is also the core of government open-data work (data.gov.in).

Explained

Sources and classification of data

HTTP, the protocol everything rides on

Parsing HTML: the DOM, selectors and libraries

APIs - the preferred route

Building a reliable scraper - the pipeline

  1. Scope: define the exact fields, the universe (how many pages/records *in total*) and the refresh frequency.
  2. Reconnaissance: robots.txt, sitemap.xml, terms of use, URL patterns, hidden JSON endpoints.
  3. Fetch layer: session, honest User-Agent, timeout, retries with backoff, per-host delay, proxy pool only if contractually allowed.
  4. Store raw: save HTML/JSON with the URL and a UTC timestamp (raw → parsed → clean is the standard three-zone layout, i.e. bronze/silver/gold).
  5. Parse: selectors into a flat record; coerce types; keep a source_url and fetched_at on every row - this is your provenance.
  6. Validate: required fields non-null, numeric ranges, row-count within expected bounds, duplicate check on a natural key. Fail loudly.
  7. Deduplicate: exact key match, then normalised match (lowercase, strip punctuation), then fuzzy (token-set ratio) for names.
  8. Incremental loads: use ETag/Last-Modified, "new since last id", or hash the content to detect change.
  9. Monitor: alert on a drop in rows scraped, a surge in 403/429, or a selector returning None - the usual symptom of a site redesign.
  10. Document: a data dictionary per field with its source, unit and collection date.
  11. Anti-bot measures you will meet: CAPTCHAs, Cloudflare/Akamai JS challenges, TLS fingerprinting, honeypot links, dynamic class names (class="css-1x9y3z" - never key on these; anchor on stable text, id, or data-* attributes).
  12. File formats for storage: CSV (universal, untyped), Parquet (columnar, compressed, typed - the default for large scrapes), JSONL (one record per line, append-friendly), SQLite/Postgres for querying.

Legal, ethical and Indian regulatory frame

Key points

Formulas and examples

Coverage % = (records successfully collected / total records in the universe) × 100
Success rate = 2xx responses / total requests × 100
Effective throughput R = C / (t_response + t_delay) pages per second; C = concurrent workers, t in seconds
Crawl time T = N / R seconds; N = number of pages
Exponential backoff wait w(k) = min(b × 2k−1 + U(0, j), w_max); k = attempt number, b = base delay (s), j = jitter (s)
Pages per paginated list P = ceil(total_items / items_per_page)
Sample size for a proportion n₀ = Z² p(1−p) / e²; finite-population correction n = n₀ / (1 + (n₀ − 1)/N)
Data volume V = N × s bytes; s = average bytes per page/record

Example 1 - crawl budget and time. A price monitor must cover 2,40,000 product pages. Average server response 0.8 s, politeness delay 0.5 s per worker, 8 concurrent workers allowed.

Example 2 - pagination and request count. A job board shows 7,480 listings, 25 per page, plus one detail page per listing.

Example 3 - exponential backoff schedule. Base b = 1 s, factor 2, jitter uniform 0-0.5 s, 5 attempts, cap 30 s.

Attempt kDeterministic b×2k−1Wait range with jitter
11 s1.0 - 1.5 s
22 s2.0 - 2.5 s
34 s4.0 - 4.5 s
48 s8.0 - 8.5 s
516 s16.0 - 16.5 s

Example 4 - coverage, success rate and sample size. A crawl of 451 Indian cities issues 12,300 requests: 11,205 return 200, 640 return 403, 455 return 429.

Example 5 - working code, static page.

import time, requests, pandas as pd
from bs4 import BeautifulSoup
from urllib.robotparser import RobotFileParser

BASE = "https://example.com/jobs"
UA = "campus-research-bot/1.0 (+contact: team@college.ac.in)"

rp = RobotFileParser(); rp.set_url("https://example.com/robots.txt"); rp.read()
assert rp.can_fetch(UA, BASE), "disallowed by robots.txt"

s = requests.Session(); s.headers["User-Agent"] = UA
rows, page = [], 1
while True:
    r = s.get(BASE, params={"page": page}, timeout=10)
    if r.status_code == 429:                       # rate limited
        time.sleep(int(r.headers.get("Retry-After", 2 ** page)))
        continue
    r.raise_for_status()
    soup = BeautifulSoup(r.text, "lxml")
    cards = soup.select("div.job-card")
    if not cards:
        break                                      # no more pages
    for c in cards:
        rows.append({
            "title":    c.select_one("h2.title").get_text(strip=True),
            "employer": c.select_one("span.employer").get_text(strip=True),
            "city":     (c.select_one("span.city") or {}).get("title"),
            "url":      requests.compat.urljoin(BASE, c.select_one("a")["href"]),
            "fetched_at": pd.Timestamp.utcnow(),
        })
    page += 1
    time.sleep(1.0)                                 # politeness delay

df = pd.DataFrame(rows).drop_duplicates(subset="url")
df.to_parquet("jobs_raw.parquet", index=False)
print(len(df), "rows from", page - 1, "pages")

Comparison table - choosing a tool.

NeedToolSpeedWhen it is wrong
Single static page, tablespandas.read_htmlFastPage is JS-rendered
Few hundred static pagesrequests + BeautifulSoupFastNeeds concurrency/retry logic
Lakhs of pages, scheduledScrapyVery fast (async)Overkill for 10 pages
Login, clicks, infinite scrollPlaywright / SeleniumSlow, RAM-heavyData available via XHR JSON
Structured, licensed dataREST/GraphQL APIFastest, stableNo API exists

Where it is used

Interview questions

Common mistakes

Related topics

Data cleaning and feature engineering · Python essentials · Python for data analysis: NumPy and pandas · SQL queries and joins · Big data and distributed storage · Data ethics and privacy law

Open in the Knowledge reader →Find jobs →