数据采集第一次作业
第一次实验作业
作业①
1):软科2020中国大学排名定向爬取实验
undefined 要求:用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020 )的数据,屏幕打印爬取的大学排名信息。
网站(http://www.shanghairanking.cn/rankings/bcur/2020 )检查查询:

检查无误,可以正常打开
完整实现代码如下:
import requests
from bs4 import BeautifulSoup
def get_university_ranking(url):
# 构造请求头,模拟浏览器访问,避免被反爬策略拦截
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:
# 发送GET请求获取目标页面内容
response = requests.get(url, headers=headers)
# 自动识别页面编码,解决中文乱码问题
response.encoding = response.apparent_encoding
# 状态码异常时主动抛出异常
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"页面请求失败,错误信息:{e}")
return []
# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(response.text, "html.parser")
# 定位排名表格的tbody主体
table_body = soup.find("tbody")
if not table_body:
print("未找到排名表格,页面结构可能已变更")
return []
# 获取表格内所有数据行
tr_list = table_body.find_all("tr")
ranking_data = []
for tr in tr_list:
td_list = tr.find_all("td")
# 过滤列数不足的无效行
if len(td_list) < 6:
continue
# 按列索引依次提取对应字段
rank = td_list[0].text.strip()
# 提取学校中文名,过滤英文与多余空白字符
school_tag = td_list[1].find("a")
school_name = school_tag.text.strip() if school_tag else td_list[1].text.strip().split()[0]
location = td_list[3].text.strip()
school_type = td_list[4].text.strip()
total_score = td_list[5].text.strip()
# 将单条数据存入字典并加入结果列表
ranking_data.append({
"排名": rank,
"学校名称": school_name,
"省市": location,
"学校类型": school_type,
"总分": total_score
})
return ranking_data
def print_ranking(data):
# 格式化打印表头
print(f"{'排名':<6}{'学校名称':<20}{'省市':<8}{'学校类型':<10}{'总分':<8}")
print("-" * 60)
# 遍历打印每条排名数据
for item in data:
print(f"{item['排名']:<6}{item['学校名称']:<20}{item['省市']:<8}{item['学校类型']:<10}{item['总分']:<8}")
if __name__ == "__main__":
target_url = "http://www.shanghairanking.cn/rankings/bcur/2020"
rank_result = get_university_ranking(target_url)
if rank_result:
print_ranking(rank_result)
结果如下:

2):心得体会
通过本次大学排名爬取作业,我掌握了requests库发送 GET 请求的基础用法,理解了 User-Agent 请求头对模拟浏览器访问的作用。同时我熟悉了 BeautifulSoup 解析 HTML 的流程,能够通过标签定位提取表格中的结构化数据
在调试过程中我也体会到,编写爬虫前先分析网页 DOM 结构是关键,只有理清标签层级关系,才能精准提取目标数据
作业②
1):模拟商城书包商品比价定向爬虫实验
undefined 要求:用requests和re库方法设计某个商城(自已选择)商品比价定向爬虫,爬取该商城,以关键词“书包”搜索页面的数据,爬取商品名称和价格。
模拟商城静态页面:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>书包搜索结果 - 模拟商城</title>
</head>
<body>
<h1>书包商品搜索结果</h1>
<div class="product-list">
<div class="product-item">
<img src="bag1.jpg" alt="">
<div class="product-name">大容量商务双肩电脑包 男士旅行背包</div>
<div class="product-price">¥89.00</div>
</div>
<div class="product-item">
<img src="bag2.jpg" alt="">
<div class="product-name">小学生减负护脊书包 男女儿童双肩包</div>
<div class="product-price">¥59.90</div>
</div>
<div class="product-item">
<img src="bag3.jpg" alt="">
<div class="product-name">韩版初高中学生书包 女款防水双肩包</div>
<div class="product-price">¥79.00</div>
</div>
<div class="product-item">
<img src="bag4.jpg" alt="">
<div class="product-name">幼儿园卡通小书包 宝宝可爱双肩包</div>
<div class="product-price">¥35.50</div>
</div>
<div class="product-item">
<img src="bag5.jpg" alt="">
<div class="product-name">大学生潮流背包 大容量运动书包</div>
<div class="product-price">¥128.00</div>
</div>
<div class="product-item">
<img src="bag6.jpg" alt="">
<div class="product-name">轻便通勤双肩包 简约休闲书包</div>
<div class="product-price">¥49.90</div>
</div>
</div>
</body>
</html>
完整实现代码如下:
import requests
import re
def get_bookbag_products(keyword):
# 本地模拟商城的页面访问地址
url = "http://localhost:8000/shop.html"
# 构造浏览器请求头,模拟正常用户访问
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:
# 发送GET请求获取页面源码
response = requests.get(url, headers=headers)
# 设置页面编码,保证中文正常显示
response.encoding = response.apparent_encoding
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"请求失败,错误信息:{e}")
return []
html_text = response.text
# 正则表达式匹配商品块,提取商品名称和价格,re.S支持跨行匹配
item_pattern = re.compile(
r'<div class="product-item">.*?<div class="product-name">(.*?)</div>.*?<div class="product-price">¥([\d.]+)</div>',
re.S
)
# 提取页面中所有符合规则的商品信息
matched_items = item_pattern.findall(html_text)
product_list = []
for name, price in matched_items:
# 整理数据格式,价格转为浮点型便于后续处理
product_list.append({
"商品名": name.strip(),
"价格": float(price)
})
return product_list
def print_products(product_list):
# 格式化输出表头
print(f"{'序号':<6}{'价格':<10}{'商品名'}")
print("-" * 80)
# 按序号遍历输出所有商品信息
for idx, item in enumerate(product_list, 1):
print(f"{idx:<6}{item['价格']:<10.2f}{item['商品名']}")
if __name__ == "__main__":
search_key = "书包"
products = get_bookbag_products(search_key)
if products:
print_products(products)
else:
print("未获取到商品信息,请检查本地服务是否启动")
结果如下:

2):心得体会
通过本次作业中自主搭建本地模拟商城的方式完成商品爬虫开发,我深入掌握了正则表达式的分组匹配用法。对比 BeautifulSoup 的 DOM 树解析,正则表达式更依赖文本特征,适合结构固定的场景提取数据
同时我也掌握了 Python 内置 HTTP 服务的启动方法,理解了本地调试爬虫的便捷性
作业③
1):网页图片批量爬取与本地保存实验
undefined 要求:爬取一个给定网页( https://news.fzu.edu.cn/yxfd.htm )或者自选网页的所有JPEG、JPG或PNG格式图片文件。
完成实现代码如下:
import requests
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin
def download_page_images(url, save_dir="fzu_images"):
# 若保存文件夹不存在,则自动创建目录
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# 模拟浏览器请求头,避免图片请求被拦截
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:
# 请求目标网页源码
response = requests.get(url, headers=headers)
response.encoding = response.apparent_encoding
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"网页请求失败:{e}")
return
# 解析页面,获取所有img标签
soup = BeautifulSoup(response.text, "html.parser")
img_tags = soup.find_all("img")
# 定义允许下载的图片格式后缀
allowed_suffix = (".jpg", ".jpeg", ".png")
success_count = 0
for img in img_tags:
# 获取图片的src属性
img_src = img.get("src")
if not img_src:
continue
# 将相对路径拼接为完整的绝对URL
img_url = urljoin(url, img_src)
# 去除URL后的参数,提取纯文件名
img_filename = os.path.basename(img_url.split("?")[0])
# 获取文件后缀并转为小写,用于格式过滤
file_suffix = os.path.splitext(img_filename)[1].lower()
# 跳过非目标格式的资源
if file_suffix not in allowed_suffix:
continue
# 构造本地保存路径,添加序号前缀避免文件名重复
save_path = os.path.join(save_dir, f"{success_count + 1}_{img_filename}")
try:
# 请求图片资源,设置超时避免长时间等待
img_resp = requests.get(img_url, headers=headers, timeout=10)
img_resp.raise_for_status()
# 以二进制模式写入文件,完成图片保存
with open(save_path, "wb") as f:
f.write(img_resp.content)
success_count += 1
print(f"已保存第{success_count}张图片:{img_filename}")
except Exception as e:
print(f"图片 {img_url} 下载失败:{e}")
continue
print(f"\n下载完成,共成功保存{success_count}张图片,存放路径:{save_dir}")
if __name__ == "__main__":
target_url = "https://news.fzu.edu.cn/yxfd.htm"
download_page_images(target_url)
结果如下:


2):心得体会
通过本次图片爬取作业,我学会了批量下载网络二进制资源的方法,掌握了urljoin函数将相对路径转换为绝对 URL 的技巧,以及os模块对本地文件、文件夹的创建与路径操作,理解了图片文件需要以二进制模式写入的原理,也学会了通过后缀名过滤目标资源的方法
调试中我遇到了图片 URL 携带参数、相对路径解析错误、单张图片超时导致程序中断等问题,通过逐一排查并添加异常处理解决了问题,加深了对 URL 组成结构的理解
浙公网安备 33010602011771号