零基础起步:从发一个请求到跑通一条链路

4 个关卡 11 个微步骤,每步写清「做什么 / 敲什么 / 你应该看到 / 报错怎么办」。走完就能独立抓一页、抽字段、存 CSV、做统计。

4 关11 个微步骤requests + lxml + BS4 + pandas
前置会一点 Python(变量、列表、字典、函数)。如果完全没写过,先去《Python 程序设计》站的“零基础起步”走一遍前 4 关。

第 0 关 · 装环境、跑通第一个请求(6 分钟)

目标采集课的门槛是环境:Python + requests + lxml + bs4 装好,发得出请求就成功了一半。
前提:已装 Python 3.8+(没有先装,勾选 Add to PATH)

1① 装依赖库

🎯 一条命令装齐本课要用的核心库。

SHELL
pip install requests lxml beautifulsoup4 pandas
👀 你应该看到
Successfully 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 拿回页面,看状态码与前几十个字符。

PYTHON
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 的请求,加上它更像浏览器。

PYTHON
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 适合结构规整的页面。

PYTHON
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 容错更好,适合结构不太规整的页面。

PYTHON
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,后面的分析才方便。

PYTHON
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 分钟)

目标采集到的数据一定有脏东西:空值、重复、格式不统一。用 pandas 处理最省事。
前提:第 1 关完成,且已有 news.csv

1① 读进来先看

🎯 读 CSV、看形状、看类型、看空值。

PYTHON
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
链接    0

shape 是(行数, 列数);isnull().sum() 看每列缺多少。

⚠️ 如果报错
  • FileNotFoundError → 文件不在当前目录;用绝对路径或先 cd 到文件所在目录
  • UnicodeDecodeError → 编码不对;read_csv(..., encoding="utf-8" 或 "gbk")

2② 去重与去空

🎯 drop_duplicates 去重,dropna 去空值。

PYTHON
df = df.drop_duplicates().dropna()
print(len(df))
👀 你应该看到
2

链式调用即可;只想去某几列的空值可写 subset=["标题"]。

3③ 分组统计

🎯 按某一列统计条数,是最常用的分析动作。

PYTHON
df["来源"] = ["校园网", "教务处"]
print(df.groupby("来源").size())
👀 你应该看到
来源
教务处    1
校园网    1

groupby().size() 统计每组行数;结果可用 plot.bar() 直接画图。

第 3 关 · Scrapy 初体验(选做,10 分钟)

目标当页面多、字段多,脚本就不够用了,该上框架。
前提:第 1 关完成

1① 建项目与爬虫

🎯 两条命令生成工程骨架。

SHELL
scrapy startproject news
cd news
scrapy genspider campus example.edu
👀 你应该看到
Created 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 验证抽取是否成功。

SHELL
scrapy crawl campus -O out.json
👀 你应该看到
… [scrapy.core.engine] INFO: Spider closed (finished)
(生成 out.json)

-O 会覆盖写;-o 是追加。先跑通再研究 Pipeline 落库。

✅ 过关标准能独立完成「请求 → 解析 → 存 CSV → pandas 统计」这四步,就可以直接看项目二~七了。