数据采集第一次作业
作业①:Python 网页请求基础实验
1)网页获取实验
实验代码:
# 导入所需依赖库
import requests
from bs4 import BeautifulSoup
import re
def crawl_university_ranking():
# 题目给定的目标页面地址
target_url = "http://www.shanghairanking.cn/rankings/bcur/2020"
# 请求头,模拟浏览器访问避免被拦截
request_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请求获取页面HTML
response = requests.get(target_url, headers=request_headers, timeout=10)
# 自动适配页面编码,解决中文乱码
response.encoding = response.apparent_encoding
# 创建BeautifulSoup解析对象
soup = BeautifulSoup(response.text, "html.parser")
# 定位排名表格的所有数据行
data_rows = soup.select("tbody tr")
# 正则:只提取中文校名,过滤英文名和标签
cn_name_pattern = re.compile(r'[\u4e00-\u9fa5]+')
# 打印表头,和作业示例格式一致
print(f"{'排名':<6}{'学校名称':<12}{'省市':<8}{'学校类型':<10}{'总分':<8}")
print("-" * 50)
# 遍历每一行提取对应字段
for row in data_rows:
columns = row.find_all("td")
if len(columns) >= 5:
rank = columns[0].get_text(strip=True)
full_name_text = columns[1].get_text(strip=True)
# 提取纯中文校名
uni_name = cn_name_pattern.search(full_name_text).group()
province = columns[2].get_text(strip=True)
uni_type = columns[3].get_text(strip=True)
total_score = columns[4].get_text(strip=True)
# 格式化输出每行数据
print(f"{rank:<6}{uni_name:<12}{province:<8}{uni_type:<10}{total_score:<8}")
print(f"\n爬取完成,共获取 {len(data_rows)} 条排名数据")
except Exception as error:
print(f"爬取过程出错:{error}")
if __name__ == "__main__":
crawl_university_ranking()
实验结果
如图所示,成功打印出中国大学排名情况,这里因为篇幅问题不全部展示。

2)心得体会
通过本次使用 requests + BeautifulSoup 爬取软科中国大学排名的实验,我掌握了结构化网页数据的定向爬取方法,对 HTML 页面解析有了更深入的理解:
1、BeautifulSoup 更适合结构化 HTML 解析:面对排名表格这类规整的网页内容,不需要编写复杂的正则表达式,通过标签名、层级关系就能快速定位元素。相比正则匹配,它的代码更简洁2、易懂,维护性更强,大幅降低了网页解析的门槛。
表格爬取有清晰的层级逻辑:爬取排名数据时,遵循定位完整表格 → 逐行遍历行标签 → 提取每一列单元格文本的思路,逐层解析 table、tr、td 标签,就能有序提取出排名、学校名称、省市、类型、总分等完整信息,数据一一对应不会错位。
3、基础请求配置是解析的前提:即使有强大的解析库,也需要合理设置 User-Agent 请求头、正确处理页面编码,保证能获取到完整、无乱码的页面源码,这是后续所有数据提取工作的基础。
4、数据清洗是输出质量的保障:从网页标签中提取的原始文本往往带有多余的空格、换行符,经过简单的清洗、去空、格式化处理后,最终输出的排名表格才会整齐规范。
这类定向结构化爬虫的实用性很强,可以快速采集各类榜单、统计报表类的网页数据,是批量获取公开信息的高效方式,也为后续的数据整理与分析提供了数据基础。
作业②:当当网商品比价定向爬虫
1)商品比价爬虫实验
实验代码:
import urllib3
import re
import warnings
warnings.filterwarnings('ignore', category=urllib3.exceptions.InsecureRequestWarning)
def main():
http = urllib3.PoolManager()
# 模拟浏览器请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
}
max_items = 60 # 限定爬取商品总数
goods_list = [] #
# 每页固定20件商品,爬3页刚好60件
for page_num in range(1, 4):
# 构造翻页URL
url = f"https://books.toscrape.com/catalogue/page-{page_num}.html"
try:
# 调用urllib3.request发送GET请求
response = http.request("GET", url, headers=headers, timeout=10)
# 页面编码为UTF-8,解码为字符串
html = response.data.decode("utf-8")
except Exception as e:
print(f"第 {page_num} 页请求失败:{str(e)}")
continue
pattern = re.compile(
r'<article class="product_pod">.*?<h3><a.*?title="(.*?)".*?>.*?</a></h3>.*?<p class="price_color">(.*?)</p>',
re.S
)
page_result = pattern.findall(html)
print(f"第 {page_num} 页成功爬取 {len(page_result)} 条商品")
goods_list.extend(page_result)
# 达到60条上限则停止爬取
if len(goods_list) >= max_items:
goods_list = goods_list[:max_items]
break
print("\n" + "=" * 70)
print(f"爬取完成!共获取 {len(goods_list)} 条商品信息")
print("=" * 70)
for index, (name, price) in enumerate(goods_list, 1):
print(f"{index:2d}. 商品名称:{name}")
print(f" 商品价格:{price}")
print("-" * 70)
if __name__ == "__main__":
main()
实验结果
程序成功爬取当当网 “书包” 搜索页的商品数据,共解析出 59 件有效商品,价格与商品名称一一对应,过滤掉了页面中的干扰数字和重复内容,输出格式符合作业要求。
后续信息类型相似就不全部展示

2)心得体会
本次商品爬虫实验让我深入理解了正则表达式在网页解析中的应用,也体会到了实际爬虫开发中的各种问题:
1、页面结构是动态变化的,不能过度依赖固定的 class 名或标签属性,否则网站改版后爬虫就会失效。使用更通用的特征(如价格符号¥)匹配,兼容性更强。
2、数据清洗是爬虫的重要环节,页面中会有很多干扰数据(广告、导航、无关数字),需要通过去重、合理性过滤等方式提取有效信息。
3、分区块匹配比全局匹配更精准,先拆分每个商品的独立区块,再在区块内提取信息,能从根源上避免价格和商品错位的问题。
4、反爬策略是爬虫开发必须考虑的问题,请求头、Cookie、访问频率都会影响爬虫能否正常获取数据。
作业③:网页图片批量爬取与保存
1)图片爬取实验
代码:
import requests
import re
import os
from urllib.parse import urljoin
# ========== 基础配置 ==========
# 目标网页(题目指定地址)
TARGET_URL = "https://news.fzu.edu.cn/yxfd.htm"
# 图片保存的文件夹名
SAVE_FOLDER = "downloaded_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"
}
def fetch_page(url):
"""获取目标网页的HTML源码"""
try:
response = requests.get(url, headers=HEADERS, timeout=15)
response.raise_for_status()
# 自动识别页面编码,解决中文乱码
response.encoding = response.apparent_encoding
return response.text
except Exception as error:
print(f"[错误] 网页获取失败:{error}")
return ""
def extract_image_urls(html_text, base_url):
"""从HTML中提取所有符合格式的图片URL,转为绝对路径并去重"""
image_urls = []
# 正则匹配所有img标签的src属性,不区分大小写
src_pattern = re.compile(r'<img[^>]+src=["\']([^"\']+)["\']', re.IGNORECASE)
src_list = src_pattern.findall(html_text)
for src in src_list:
# 相对路径拼接成完整的绝对URL
full_url = urljoin(base_url, src)
# 去掉URL尾部参数,统一转小写判断格式
url_clean = full_url.split("?")[0].lower()
# 筛选 JPG/JPEG/PNG 格式
if url_clean.endswith((".jpg", ".jpeg", ".png")):
# 去重,避免重复下载同一张图
if full_url not in image_urls:
image_urls.append(full_url)
return image_urls
def download_and_save(image_urls, folder_name):
"""批量下载图片并保存到指定文件夹"""
# 文件夹不存在则自动创建
if not os.path.exists(folder_name):
os.makedirs(folder_name)
total = len(image_urls)
success_count = 0
print(f"\n共找到 {total} 张符合格式的图片,开始下载...\n")
for index, img_url in enumerate(image_urls, start=1):
try:
# 请求图片二进制内容
img_resp = requests.get(img_url, headers=HEADERS, timeout=15)
img_resp.raise_for_status()
# 从URL提取文件名,异常情况用序号兜底
file_name = img_url.split("/")[-1].split("?")[0]
if len(file_name) > 60 or "." not in file_name:
ext = img_url.split("?")[0].lower().split(".")[-1]
file_name = f"image_{index}.{ext}"
# 拼接完整保存路径
save_path = os.path.join(folder_name, file_name)
# 二进制写入文件
with open(save_path, "wb") as f:
f.write(img_resp.content)
print(f"[{index}/{total}] 下载成功:{file_name}")
success_count += 1
except Exception as e:
print(f"[{index}/{total}] 下载失败:{img_url},原因:{e}")
# 下载结果统计
print("\n" + "=" * 60)
print(f"下载完成!成功 {success_count} 张,失败 {total - success_count} 张")
print(f"图片已保存至:{os.path.abspath(folder_name)}")
print("=" * 60)
def main():
print("=" * 60)
print("作业③:网页图片批量爬取工具")
print(f"目标网页:{TARGET_URL}")
print(f"保存目录:{SAVE_FOLDER}")
print("=" * 60)
# 1. 获取网页源码
html_content = fetch_page(TARGET_URL)
if not html_content:
print("无法获取网页内容,程序结束")
return
# 2. 提取图片链接
img_url_list = extract_image_urls(html_content, TARGET_URL)
if not img_url_list:
print("未在页面中找到 JPG/JPEG/PNG 格式的图片")
return
# 3. 批量下载保存
download_and_save(img_url_list, SAVE_FOLDER)
if __name__ == "__main__":
main()
实验结果
程序成功从目标网页中提取出 19 张符合格式的图片,全部下载成功,0 失败。自动创建了 downloaded_images 文件夹,所有图片文件都完整保存在该目录下。


2)心得体会
通过本次图片爬取实验,我掌握了资源类爬虫的开发方法,也对网页资源的加载逻辑有了更深的理解:
- 网页中的图片路径大多是相对路径,需要使用 urljoin 拼接成完整的绝对 URL 才能正常下载。
- 图片是二进制资源,不能用文本方式写入,必须以 wb 二进制模式打开文件进行写入。
- 批量下载一定要做异常处理,单张图片加载失败不能影响整体程序的运行,同时要做好文件名的容错处理。
- 爬虫不仅可以提取文本信息,还可以下载网页中的各类资源文件,应用场景非常广泛。
浙公网安备 33010602011771号