零基础起步:从发一个请求到跑通一条链路
4 个关卡 11 个微步骤,每步写清「做什么 / 敲什么 / 你应该看到 / 报错怎么办」。走完就能独立抓一页、抽字段、存 CSV、做统计。
第 0 关 · 装环境、跑通第一个请求(6 分钟)
前提:已装 Python 3.8+(没有先装,勾选 Add to PATH)
1① 装依赖库
🎯 一条命令装齐本课要用的核心库。
pip install requests lxml beautifulsoup4 pandasSuccessfully installed requests-2.31.0 …
出现 Successfully installed 即成功;已装过会显示 Requirement already satisfied。
'pip' 不是内部或外部命令→ 没配 PATH;用 python -m pip install 代替Read timed out→ 网络慢;加国内源:-i https://pypi.tuna.tsinghua.edu.cn/simple
2② 第一个请求
🎯 requests.get 拿回页面,看状态码与前几十个字符。
import requests
r = requests.get("https://www.python.org", timeout=10)
print(r.status_code)
print(r.text[:60])200 <!doctype html> <html lang="en">…
200 表示成功;返回的 r.text 就是整个 HTML 源码。
SSLError→ 证书问题;加 verify=False(仅调试)ProxyError / ConnectionError→ 代理或网络不通;检查网络、关代理后重试
3③ 加上请求头
🎯 很多站点会拦没有 User-Agent 的请求,加上它更像浏览器。
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
r = requests.get("https://www.python.org", headers=headers, timeout=10)
print(r.status_code)200
headers 是一个字典,可同时加 Referer、Cookie 等。
第 1 关 · 解析页面:把 HTML 变成字段(8 分钟)
前提:第 0 关完成
1① XPath 提取链接
🎯 lxml + XPath 适合结构规整的页面。
from lxml import etree
html = '<ul><li><a href="/n1">新闻一</a></li><li><a href="/n2">新闻二</a></li></ul>'
tree = etree.HTML(html)
print(tree.xpath("//a/@href"))
print(tree.xpath("//a/text()"))['/n1', '/n2'] ['新闻一', '新闻二']
//a 表示任意层级的 a 标签;@href 取属性,text() 取文本。
XPath 返回空列表→ 路径写错或页面结构与预期不同;先 print(tree.xpath("//a")) 看能不能选到节点
2② BeautifulSoup 提取
🎯 BS4 容错更好,适合结构不太规整的页面。
from bs4 import BeautifulSoup
html = '<div class="news"><a href="/n1">新闻一</a></div>'
soup = BeautifulSoup(html, "html.parser")
a = soup.select_one("div.news a")
print(a.get_text(strip=True), a["href"])新闻一 /n1
select 用 CSS 选择器;get_text(strip=True) 去掉多余空白。
3③ 存成表
🎯 把字段整理成列表再存 CSV,后面的分析才方便。
import csv
rows = [{"标题": "新闻一", "链接": "/n1"}]
with open("news.csv", "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["标题", "链接"])
w.writeheader()
w.writerows(rows)
print("已保存 news.csv")已保存 news.csv
newline="" 可避免 Windows 下多出空行。
第 2 关 · 清洗与分析(8 分钟)
前提:第 1 关完成,且已有 news.csv
1① 读进来先看
🎯 读 CSV、看形状、看类型、看空值。
import pandas as pd
df = pd.read_csv("news.csv")
print(df.shape)
print(df.head())
print(df.isnull().sum())(2, 2)
标题 链接
0 新闻一 /n1 …
标题 0
链接 0shape 是(行数, 列数);isnull().sum() 看每列缺多少。
FileNotFoundError→ 文件不在当前目录;用绝对路径或先 cd 到文件所在目录UnicodeDecodeError→ 编码不对;read_csv(..., encoding="utf-8" 或 "gbk")
2② 去重与去空
🎯 drop_duplicates 去重,dropna 去空值。
df = df.drop_duplicates().dropna()
print(len(df))2
链式调用即可;只想去某几列的空值可写 subset=["标题"]。
3③ 分组统计
🎯 按某一列统计条数,是最常用的分析动作。
df["来源"] = ["校园网", "教务处"]
print(df.groupby("来源").size())来源 教务处 1 校园网 1
groupby().size() 统计每组行数;结果可用 plot.bar() 直接画图。
第 3 关 · Scrapy 初体验(选做,10 分钟)
前提:第 1 关完成
1① 建项目与爬虫
🎯 两条命令生成工程骨架。
scrapy startproject news
cd news
scrapy genspider campus example.eduCreated scrapy project "news" Created spider "campus"
项目里有 spiders/、items.py、pipelines.py、settings.py。
scrapy 不是内部或外部命令→ 没装或不在 PATH;pip install scrapy,或用 python -m scrapy
2② 跑起来看输出
🎯 先不加 Pipeline,直接用 -O 输出 json 验证抽取是否成功。
scrapy crawl campus -O out.json… [scrapy.core.engine] INFO: Spider closed (finished) (生成 out.json)
-O 会覆盖写;-o 是追加。先跑通再研究 Pipeline 落库。