上一篇只看不抓,把网页的骨架摸熟了;今天动手:装上 BeautifulSoup 这把”万能钥匙”,把网页里的东西真真切切”取”下来、存成自己的文件。你会发现爬虫根本不是黑客技术——它就是”看懂结构 + 按图索骥”,而按图索骥的功夫,你上一篇已经练完了。
一、还是那张值班表,今天不加班了
先把上一篇欠的账摆上桌。
上次你遇到的事:单位公告栏网页上挂着一张值班表,领导让你整理成 Excel 存档,每周一次。你已经学会了”看”网页骨架——右键查看源代码,找到那个
| 周一 | 张三 |
| 周二 | 李四 |
| 周三 | 王五 |
看着眼熟吧?这就是上一篇”看”的那个骨架。现在写 spider1.py:
from bs4 import BeautifulSoup
# 第1步:拿到网页源码(今天先从本地文件读,模拟"取回来的源码")
with open("值班表.html", encoding="utf-8") as f:
html = f.read()
# 第2步:交给管家,拆成套娃结构
soup = BeautifulSoup(html, "html.parser")
# 第3步:按名字取东西
title = soup.find("h1").get_text() # 找到 h1 盒子,取出文字
print("标题是:", title)
rows = soup.find_all("tr") # 把所有 tr 盒子都拿出来
for row in rows:
cells = row.find_all("td") # 每个 tr 里再找 td 小盒子
day = cells[0].get_text()
name = cells[1].get_text()
print(day, "值班的是", name)
运行:
python spider1.py
预期输出:
标题是: 2026年10月值班表
周一 值班的是 张三
周二 值班的是 李四
周三 值班的是 王五
恭喜,这是你人生第一个爬虫。是的,就这么几行。爬虫的”神秘感”今天正式破除:取源码(requests/open)→ 拆结构(BeautifulSoup)→ 按名取物(find / find_all)→ 拿到手(get_text)。四步,一步都不能少,但也一步都不难。
代码里有个小细节留意一下:BeautifulSoup(html, "html.parser") 里那个 "html.parser" 是”用哪把剪刀拆套娃”——Python 自带的剪刀,不用额外装,今天全程用它。
换成真网页:把”取源码”那一步换掉
本地文件练熟了,换真网页只需要改一行——把”读文件”换成”发请求”:
import requests
from bs4 import BeautifulSoup
# 对比上一个程序:只有这一段是新的
resp = requests.get("https://example.com", timeout=10)
resp.encoding = "utf-8"
html = resp.text
soup = BeautifulSoup(html, "html.parser")
print(soup.find("h1").get_text())
看到了吗?BeautifulSoup 部分一个字都没变。这就是分层的好处:requests 负责”把源码取回来”,BeautifulSoup 负责”在源码里找东西”,各干各的,换谁都不影响谁。你现在可以把任何网页的源码喂给刚才那个”拆套娃 + 按名取物”的套路。
用哪个真实网站练手?
https://example.com是个专门给人练习的极简页面,永远稳定,最适合第一次。等你手熟了,再去抓你自己单位的公告页——那才是这篇课真正的靶子。
存下来:抓到的东西要落袋为安
抓到手只是成功一半,存成文件才算闭环。接着上面的代码写:
# 把抓到的值班表存成 CSV(第25篇的手艺你还记得吧)
import csv
lines = [["周一", "张三"], ["周二", "李四"], ["周三", "王五"]] # 前面循环里抓到的数据
with open("值班表.csv", "w", encoding="utf-8-sig", newline="") as f:
writer = csv.writer(f)
writer.writerow(["日期", "姓名"])
writer.writerows(lines)
print("已保存到 值班表.csv")
utf-8-sig 这个参数是给 Excel 准备的——不加它,中文在 Excel 里会显示成乱码(第25篇的坑,复习一下)。到这儿,”每周手工整理十分钟”的活儿,正式变成”运行一次脚本三秒钟”。
三、跟AI说需求 → 读懂 → 改进
老规矩,这个学习法是本系列的主心骨,今天走一遍完整流程,让你看看怎么用AI把刚才的程序”越改越像正经软件”。
第一步:跟AI说需求
把需求说具体,别只说”帮我写爬虫”。参考这个说法:
“我想抓一个网页上的值班表。表的结构是:一个
里有很多
,每行两个 ,第一个是日期、第二个是姓名。请帮我写 Python 代码:用 requests 取源码,用 BeautifulSoup 把每行的日期和姓名抓出来,打印出来,并且保存成 CSV 文件(带表头)。网页先用本地文件 值班表.html 测试。” 看出来了吗?这段话里最重要的不是”帮我写代码”,而是你把网页结构描述清楚了——上一篇练习3练的就是这个。AI 拿到这种需求,一次就能写对;你说”帮我抓个网页”,它只能猜,猜错了你还得返工。
第二步:读懂AI给的代码
AI 给你的代码大概率和上面的差不多。读懂的标准不是”能默写”,而是能回答三个问题:
- 哪一行负责”取源码”?(
requests.get/open)- 哪一行负责”拆结构”?(
BeautifulSoup(...))- 哪一行负责”按名字取”,名字是哪来的?(
find('table')里的'table',名字来自你观察网页源码时看到的标签名)能答上这三个问题,你就真的读懂了。答不上?把对应那行代码单独贴给AI:”这行在干什么?用比喻解释。”
第三步:改进
读懂之后提新要求,让程序更皮实。比如:
“现在有两个问题帮我改:①如果网页上某天没排班,
只有一个,我的代码会报错’列表索引超出范围’,怎么处理?②我希望运行时先打印’正在抓取…’,抓完了打印’共抓到N条’。” AI 大概率会教你用
try/except(第10篇的手艺)或者if len(cells) >= 2:判断(第5篇的手艺),再加上两个四、四个必踩的坑(先打疫苗)
坑1:忘了
get_text(),抓出来一堆标签。soup.find("h1")拿到的是整个盒子(连标签带内容),直接2026年10月值班表
这样一坨。你想要纯文字,就得
.get_text()。疫苗:拿到东西先问自己”我要的是盒子还是盒子里的文字”——要文字,加.get_text();要属性(比如链接地址),用.get('href')。坑2:
find和find_all分不清,一个返回单个、一个返回列表。find找第一个,返回的是一个盒子(可以直接.get_text());find_all找全部,返回的是列表,必须 for 循环遍历后再取文字。最常见的报错是'ResultSet' object has no attribute 'get_text'——意思就是”你对一个列表喊 get_text,列表没有这个本事”。疫苗:要用循环的,一定是 find_all;不循环直接取文字的,一定是 find。坑3:抓真实网页时忘了
resp.encoding,中文全变乱码。有些网站(尤其是国内网站)用的不是 UTF-8 编码,resp.text直接读会给你一屏”锟斤拷”。疫苗:取完源码先加一行resp.encoding = resp.apparent_encoding(让 requests 自己猜编码)或resp.encoding = "utf-8",能挡掉八成乱码问题。本地文件读取同理,open(..., encoding="utf-8")不能省。坑4:
find找不到东西时返回None,然后程序崩在下一行。soup.find("table")如果网页里根本没有,返回的是
None,你接着.get_text()就报'NoneType' object has no attribute 'get_text'。疫苗:真网站的结构随时会变,找不到是常态不是意外。先table = soup.find("table"),再if table is None: print("没找到表格,网页结构可能变了"); exit()。这个小习惯下一篇、下下一篇全用得上——爬虫是跟”会变的东西”打交道,防御性检查不是可选项。五、跟AI协作的正确姿势(抓数据特供)
- 喂”一小段源码”,不要喂”整个网页”。上一篇说过:几万行源码全丢给AI,它也会看花眼。正确姿势是:你在源码里 Ctrl+F 搜到”值班”两个字,把它前后各几十行复制给AI,说”数据在这个区域里,帮我写提取代码”。精准打击。
- 让AI解释”选择器”,而不是替你猜选择器。AI 猜的
class名可能根本不准。更稳的流程是:你用 F12 查看器亲自确认”这个表格的 class 叫duty-table“,然后让AI”用 class_=’duty-table’ 来定位”。定位你来,写码它来。- 让AI写”报错处理”,这是爬虫的灵魂。写完提取代码,多问一句:”如果这个标签找不到、或者某行少一个格子,帮我加上友好的错误处理,让程序不崩、而是告诉我哪里出问题了。”会报错的爬虫满街都是,能优雅报错的爬虫才是你的生产力工具。
- 改完先跑本地文件,再跑真网页。AI 给的代码,先拿
值班表.html这种”自己可控的网页”跑通,确认提取逻辑没问题,再换成真网址。一步到位跑真网页,出了错你都不知道是”取源码”错了还是”找东西”错了——分层测试,是从第12篇就教你的老办法。六、今日小练习
练习1:跑通你的第一个爬虫。照抄第二节的
值班表.html和spider1.py,运行并核对输出。然后改一个需求:把周三的值班人改成你自己的名字(改 HTML 文件即可),重新运行,确认程序抓到的是”改过之后”的值。提示:这题练的是”程序读的是文件里的当前内容”这个直觉——改文件就能改结果,不用改代码。如果改完输出没变,检查你保存的是不是同一个
值班表.html。练习2:让程序多抓一样东西。在
值班表.html的下面加一行
(其实文件里已经有了),修改发布日期:2026-10-17
spider1.py,让它在打印标题之后,再打印出发布日期。提示:
p盒子就在h1旁边,用soup.find("p")就能拿到。这题是为下一题热身——从”抓固定几样”到”抓任意几样”,其实只差一个 find。练习3(动脑题):给”抓全校课表”写需求。假设学校网站上有一个课表页面(想象它有
、每周七天、每天五六节课),把你要跟AI说的需求写下来:目标、网页结构、输出格式(存成CSV还是直接打印)、可能出什么错。写得越具体越好。
提示:对照第一节那段”参考需求”的结构写——目标、结构、输出、容错,四要素齐了就是好需求。写完留着,下一篇(提取表格数据)你把这段话直接粘给AI,多半一次就能用。
下篇预告
下一篇(第42篇):提取表格数据 — 把真正的”一张大表”完整搬回家。今天你抓的是三行小表,下一篇上强度:多列的表格、带表头的表格、合并单元格的表格,还要让程序自动”数一数表里有几行几列”。套路不变(find + get_text),变的是”按图索骥”的图更复杂一点。你今天已经拿到了钥匙,下一篇练的是开更多种锁。
评论
发表回复