Level: Advanced | Prerequisite: Week 6
Learning Goals
- HTTP requests with
requests - Parse HTML with
BeautifulSoup - Handling headers, sessions, and cookies
- robots.txt and etiquette
1. requests
import requests
r = requests.get("https://example.com")
print(r.status_code) # 200
print(r.text[:200]) #Some HTML
print(r.headers["Content-Type"])
# JSON API
r = requests.get("https://api.github.com/users/python")
data = r.json()
print(data["public_repos"])
2. POST Requests
r = requests.post("https://httpbin.org/post",
data={"key": "value"},
headers={"User-Agent": "MyBot 1.0"},
)
3. BeautifulSoup
pip install beautifulsoup4 lxml
from bs4 import BeautifulSoup
html = """<html><body>
<h1>Title</h1>
<ul>
<li class="item">A</li>
<li class="item">B</li>
</ul>
</body></html>"""
soup = BeautifulSoup(html, "html.parser")
print(soup.h1.text)
print(soup.find("h1").text)
print([li.text for li in soup.find_all("li")])
print([li.text for li in soup.select("li.item")]) #CSS Selector
4. Sessions and Cookies
session = requests.Session()
session.headers.update({"User-Agent": "Mozilla/5.0"})
#Login
session.post("https://example.com/login", data={"user": "x", "pass": "y"})
#Request with the same session → Keep cookies
r = session.get("https://example.com/me")
5. Etiquette and Ethics
- Check robots.txt:
https://example.com/robots.txt - Request intervals: Recommended around
time.sleep(1) - User agent: Display honestly
- Copyright and terms compliance
6. Practical Patterns
import requests
from bs4 import BeautifulSoup
import time
URL = "https://news.ycombinator.com"
HEADERS = {"User-Agent": "Mozilla/5.0 (study)"}
def fetch_titles():
r = requests.get(URL, headers=HEADERS, timeout=10)
r.raise_for_status()
soup = BeautifulSoup(r.text, "html.parser")
titles = [a.get_text() for a in soup.select(".titleline > a")]
return titles[:10]
for i, title in enumerate(fetch_titles(), 1):
print(f"{i}. {title}")
Key Examples (examples/)
| File | Content |
|---|---|
01_requests_basic.py |
GET, JSON |
02_bs4_parse.py |
HTML Parsing |
03_session.py |
Session + Cookies |
04_scrape_demo.py |
Actual Scraping (httpbin) |
⚠️ Common Mistakes
- Missing timeout — Risk of infinite wait. Always around
timeout=10. - Not checking
r.raise_for_status()— Can't detect 404. - HTML parser not specified — Explicitly
"html.parser"or"lxml". - Selectors too fragile — id/class changes often. Use robust selectors.
- Getting blocked — Requests are too fast. Interval of
time.sleep.
❓ FAQ
Q1. Pages rendered by JavaScript? A. Cannot be done with requests. Use Selenium or Playwright.
Q2. What is a dynamic site? A. Usually calls the internal API directly (found in Developer Tools → Network tab).
Q3. How to fetch a page after logging in? A. Use a session. You may also need to handle the CSRF token.
📝 Exercises (exercises/)
exercise1.md— Top 10 news headlinesexercise2.md— GitHub user repository informationexercise3.md— Function to check robots.txt
Next Week
Week 8. NumPy / Pandas