作业1
爬取大学排名信息实验
完整代码
import requests
from bs4 import BeautifulSoup
def get_university_ranking():
url = "http://www.shanghairanking.cn/rankings/bcur/2020"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
}
try:
r = requests.get(url, headers=headers, timeout=10)
r.raise_for_status()
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, "html.parser")
# 打印表头
print(f"{'排名':<6}{'学校名称':<16}{'省市':<8}{'学校类型':<8}{'总分':<8}")
# 软科页面表格行为 tr,数据在 td 中
table = soup.find("table")
if not table:
print("未找到表格,页面可能为动态渲染,需改用接口抓取。")
return
rows = table.find_all("tr")
for row in rows[1:]:
tds = row.find_all("td")
if len(tds) < 5:
continue
rank = tds[0].get_text(strip=True)
name = tds[1].get_text(strip=True).split("\n")[0]
province = tds[2].get_text(strip=True)
school_type = tds[3].get_text(strip=True)
score = tds[4].get_text(strip=True)
print(f"{rank:<6}{name:<16}{province:<8}{school_type:<8}{score:<8}")
except Exception as e:
print("爬取失败:", e)
if __name__ == "__main__":
get_university_ranking()
结果展示


心得体会
首先,我认识到“伪装”的重要性。通过在 headers 中设置 User-Agent,模拟真实浏览器发送请求,有效避免了被服务器拒绝访问。其次,我体会到了 BeautifulSoup 解析库的强大。面对庞大的 HTML 代码,它将其转化为清晰的 DOM 树,利用 find() 和 find_all() 能够精准定位到表格、行和单元格。
最关键的是数据清洗环节。网页文本常夹杂换行符和标签,我学会了使用 get_text(strip=True) 提取纯文本,并用 split() 剔除干扰,最终将数据按指定格式整齐打印。
这次实践让我明白,爬虫的核心不在于写代码,而在于看懂网页结构,并精准定位目标数据。同时,代码中引入的 try...except 异常捕获,也极大提升了程序的健壮性,让我对网页数据抓取有了更系统、立体的认识。
作业2
定向爬取商品名称和价格实验
完整代码
import re
import requests
from urllib.parse import quote
def get_dangdang_products(keyword="书包"):
url = "http://search.dangdang.com/?key=" + quote(keyword)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Referer": "http://www.dangdang.com/"
}
try:
r = requests.get(url, headers=headers, timeout=10)
r.encoding = "gbk" # 当当网必须用 gbk 编码
html = r.text
# 【关键排查】:看看页面里到底有没有我们要的东西
print(f"网页长度: {len(html)}")
print(f"页面是否包含'书包': {'书包' in html}")
# 1. 切割商品块:当当网的每个商品都在 <li class="line1">, line2, line3 等标签里
items = re.findall(r'<li[^>]*class="line\d"[^>]*>.*?</li>', html, re.S)
print(f"\n{'序号':<6}{'价格':<12}{'商品名'}")
print("-" * 80)
count = 0
for item in items:
# 2. 提取商品名:取 <a> 标签里的 title 属性,这样可以避开高亮标签 <font>
name_match = re.search(r'<a[^>]*title="([^"]+)"', item)
# 3. 提取价格:当当网现价通常用 ¥ (即 ¥),用 [¥¥]+ 兼容两种情况
price_match = re.search(r'<span class="price_n">\s*(?:¥|¥)\s*([\d.]+)\s*</span>', item)
if name_match:
name = name_match.group(1).strip()
# 如果没找到价格,就显示"未知"
price = price_match.group(1) if price_match else "未知"
count += 1
print(f"{count:<6}{price:<12}{name}")
if count == 0:
print("未匹配到商品块,建议把 html 保存下来检查结构。")
except Exception as e:
print("请求出错:", e)
if __name__ == "__main__":
get_dangdang_products("书包")
结果展示

心得体会
起初我尝试用 requests 爬取京东,却发现现实远比课本复杂。京东拥有极严的反爬机制,直接请求只能拿到“验证拦截页”;即使通过F12抓包复制了 Cookie 绕过验证,拿到的网页源码里也根本没有商品数据,因为商品价格和详情是由 JavaScript 动态渲染的。这让我深刻认识到静态请求的局限性。
为了完成用 re 库提取数据的要求,我果断调整策略,转向了结构更传统、对静态爬虫更友好的当当网。在这个过程中,我熟练掌握了正则表达式的高级用法:用
这次“一波三折”的实践让我明白:爬虫不是一套代码走天下,而是与网站风控的博弈。只有学会通过 F12 抓包分析请求,灵活应对动态加载,并在遇到阻碍时及时“曲线救国”更换目标,才能真正拿到想要的数据。
作业3
网页图片下载爬虫实验
完整代码
import os
import requests
from bs4 import BeautifulSoup
def download_images(url="https://news.fzu.edu.cn/yxfd.htm", save_dir="images"):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
}
os.makedirs(save_dir, exist_ok=True)
try:
r = requests.get(url, headers=headers, timeout=10)
r.raise_for_status()
r.encoding = r.apparent_encoding
soup = BeautifulSoup(r.text, "html.parser")
img_tags = soup.find_all("img")
count = 0
for img in img_tags:
src = img.get("src") or img.get("data-src")
if not src:
continue
# 补全相对地址
if src.startswith("//"):
src = "https:" + src
elif src.startswith("/"):
src = "https://news.fzu.edu.cn" + src
elif not src.startswith("http"):
src = "https://news.fzu.edu.cn/" + src
if not src.lower().endswith((".jpg", ".jpeg", ".png")):
continue
try:
img_data = requests.get(src, headers=headers, timeout=10).content
filename = os.path.join(save_dir, src.split("/")[-1].split("?")[0])
with open(filename, "wb") as f:
f.write(img_data)
print("已保存:", filename)
count += 1
except Exception as e:
print("图片下载失败:", src, e)
print(f"共保存 {count} 张图片到 {save_dir}/")
except Exception as e:
print("网页爬取失败:", e)
if __name__ == "__main__":
download_images()
结果展示


心得体会
本次爬虫的核心流程清晰明确:先使用 requests 获取网页源码,再用 BeautifulSoup 定位所有的 img 标签。但真正的挑战在于后续的数据落地环节。
首先,我学会了绝对路径的补全。网页源码中的图片链接常常是相对路径(如 /upload/...)或以 // 开头的省略协议路径。如果不进行 if 判断并拼接主域名,程序会直接报错。其次,我掌握了目录创建与二进制写入。通过 os.makedirs(save_dir, exist_ok=True) 防止文件夹存在报错,并在下载图片时严格使用 'wb'(二进制写)模式,确保图片文件不被损坏。最后,我还加入了对 .jpg、.png 等后缀的正则和判断,实现了对目标图片的定向过滤。
这次实践让我明白,爬虫不仅是“抓取”文本,更是“搬运”资源。处理好每一个细节,才能让程序稳定、高效地跑通,将海量网络资源真正落地到本地。
浙公网安备 33010602011771号