数据采集第一次作业
数据采集第一次作业
学号:102402134
姓名:王世豪
课程:数据采集与融合技术
作业链接:第一次作业
作业①:大学排名信息爬取
1. 代码与运行结果
实验要求
使用 requests 和 BeautifulSoup 库,定向爬取 2020 年软科中国大学排名 页面,在屏幕上打印大学排名信息。输出字段包括:排名、学校名称、省市、学校类型和总分。
本次实现首先使用 requests 获取网页数据,并使用 BeautifulSoup 解析 HTML 表格。当网页采用 Nuxt.js 静态载荷提供完整排名数据时,程序会进一步解析 payload.js,获取更多学校记录;如果静态载荷不可访问,则自动回退到 HTML 表格解析。
关键代码
import requests
from bs4 import BeautifulSoup
def fetch_page(url):
"""使用 requests 获取网页内容。"""
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"
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
response.encoding = "utf-8"
return response.text
def parse_table(html):
"""使用 BeautifulSoup 提取排名表格中的前五列。"""
soup = BeautifulSoup(html, "html.parser")
result = []
tbody = soup.find("tbody")
if tbody is None:
raise ValueError("未找到排名表格")
for tr in tbody.find_all("tr"):
cells = tr.find_all("td", recursive=False)
if len(cells) < 5:
continue
name_node = cells[1].select_one(".name-cn")
name = name_node.get_text(strip=True) if name_node else cells[1].get_text(strip=True)
result.append([
cells[0].get_text(strip=True),
name,
cells[2].get_text(strip=True),
cells[3].get_text(strip=True),
cells[4].get_text(strip=True),
])
return result
def print_rankings(rows):
"""以表格形式打印排名信息。"""
print("排名\t学校名称\t省市\t学校类型\t总分")
print("-" * 70)
for rank, name, province, category, score in rows[:20]:
print(f"{rank}\t{name}\t{province}\t{category}\t{score}")
url = "http://www.shanghairanking.cn/rankings/bcur/2020"
html = fetch_page(url)
rankings = parse_table(html)
print_rankings(rankings)
说明:博客中展示的是核心解析代码,完整可运行代码见同目录下的
work1.py。完整代码还包含 Nuxt.jspayload.js的解析和异常回退处理。
运行结果
程序实际运行后,成功解析到排名数据,并打印前 20 所学校。部分结果如下:

2. 心得体会
本次实验让我熟悉了定向爬虫的基本流程:先使用 requests 发送请求,再使用 BeautifulSoup 定位 HTML 元素,最后对提取结果进行清洗和格式化输出。通过观察页面结构,我发现学校名称单元格中还包含英文名称和学校标签,因此不能简单地把整个单元格文本作为学校名称,而应优先定位中文名称节点。
实验中还遇到了网页数据并不完全位于静态 HTML 表格中的情况。通过查看网络请求,发现页面使用了 Nuxt.js 的静态数据载荷,于是增加了载荷解析逻辑,并保留 HTML 表格解析作为回退方案。这让我认识到,爬虫程序除了完成正常路径,还应考虑网页改版、请求失败和数据结构变化等情况。
作业②:商城商品比价定向爬虫
1. 代码与运行结果
实验要求
使用 requests 和 re 库设计商城商品比价定向爬虫,以“书包”为关键词搜索商城页面,提取商品名称和价格。
本次选择当当网,搜索地址为:当当网书包搜索页。程序使用正则表达式提取商品名称和商品价格,并在控制台中按照序号、价格、商品名的顺序输出。
关键代码
import re
import requests
def fetch_page(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"
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
response.encoding = "gbk"
return response.text
def parse_products(source):
"""使用正则表达式提取商品名称和价格。"""
name_pattern = r'<a\s+title="([^"]*)"[^>]*class="pic"[^>]*>'
price_pattern = r'<span\s+class="price_n">(?:¥|¥)([^<]*)</span>'
names = re.findall(name_pattern, source)
prices = re.findall(price_pattern, source)
products = []
for name, price in zip(names, prices):
name = re.sub(r"\s+", " ", name).strip()
products.append((name, price.strip()))
return products
url = "http://search.dangdang.com/?key=书包&act=input"
source = fetch_page(url)
products = parse_products(source)
print("序号\t价格\t商品名")
for index, (name, price) in enumerate(products, 1):
print(f"{index}\t¥{price}\t{name}")
说明:博客中展示的是核心代码,完整可运行代码见同目录下的
work2.py。完整代码还包含请求异常处理、编码检测和调试信息输出。
运行结果
程序实际运行后,从当当网“书包”搜索结果中提取到 60 个商品。部分结果如下:

2. 心得体会
本次实验练习了使用正则表达式从网页源码中提取结构化信息。首先分别设计商品名称和价格的匹配规则,再使用 zip 将两个结果列表配对,可以得到商品名与价格的对应关系。由于网页源码中的人民币符号可能以 ¥ HTML 实体形式存在,程序同时兼容了 HTML 实体和直接显示的人民币符号。
在调试过程中,我还注意到网页编码会影响中文内容的显示。当当网搜索页使用 GBK 兼容编码,因此请求成功后需要正确设置响应编码,否则商品名称会出现乱码。这个实验让我认识到,网页抓取不仅是写出正则表达式,还需要关注字符编码、页面结构和异常情况。
作业③:网页图片爬取与下载
1. 代码与运行结果
实验要求
爬取一个给定网页或自选网页中的所有 JPEG、JPG 或 PNG 格式图片文件,并将图片保存到一个文件夹中。
本次选择福州大学新闻网的“影像福大”页面:https://news.fzu.edu.cn/yxfd.htm。程序提取网页中的图片链接,将相对路径转换为绝对 URL,再逐张下载到 作业3图片 文件夹中。
关键代码
import os
import re
from pathlib import Path
from urllib.parse import urljoin, urlparse
import requests
def fetch_page(url):
"""获取网页源代码。"""
response = requests.get(
url,
headers={"User-Agent": "Mozilla/5.0"},
timeout=30,
)
response.raise_for_status()
response.encoding = "utf-8"
return response.text
def extract_image_urls(source, base_url):
"""提取并规范化 JPG、JPEG、PNG 图片 URL。"""
raw_urls = set()
# 提取 img 标签中的 src
for match in re.finditer(
r'<img[^>]+src\s*=\s*["\']([^"\']+)["\']',
source,
re.IGNORECASE,
):
raw_urls.add(match.group(1))
# 提取懒加载图片属性
for match in re.finditer(
r'data-(?:src|original)\s*=\s*["\']([^"\']+)["\']',
source,
re.IGNORECASE,
):
raw_urls.add(match.group(1))
image_urls = set()
for raw_url in raw_urls:
full_url = urljoin(base_url, raw_url)
suffix = Path(urlparse(full_url).path).suffix.lower()
if suffix in {".jpg", ".jpeg", ".png"}:
image_urls.add(full_url)
return sorted(image_urls)
def download_image(url, folder, number):
"""下载一张图片并保存到目标文件夹。"""
response = requests.get(
url,
headers={"User-Agent": "Mozilla/5.0"},
timeout=30,
stream=True,
)
response.raise_for_status()
original_name = os.path.basename(urlparse(url).path)
file_path = Path(folder) / f"{number:03d}_{original_name}"
with open(file_path, "wb") as image_file:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
image_file.write(chunk)
return file_path
url = "https://news.fzu.edu.cn/yxfd.htm"
output_folder = Path(__file__).resolve().parent / "作业3图片"
output_folder.mkdir(exist_ok=True)
html = fetch_page(url)
image_urls = extract_image_urls(html, url)
print(f"共发现 {len(image_urls)} 个图片链接")
for number, image_url in enumerate(image_urls, 1):
download_image(image_url, output_folder, number)
print(f"图片已保存到:{output_folder}")
说明:博客中展示的是核心下载代码,完整可运行代码见同目录下的
work3.py。完整代码还兼容 CSS 背景图片、下载异常和重名文件处理。
运行结果
程序实际运行后,共发现并成功下载 22 张 JPG/PNG 图片,文件保存在 作业3图片 文件夹中。


2. 心得体会
本次实验练习了网页图片资源的提取和二进制文件保存。图片链接可能是绝对路径,也可能是相对路径,所以需要使用 urljoin 将其转换为完整地址;下载图片时不能使用普通文本模式写入,而应使用二进制模式保存响应内容。
此外,网页中可能同时存在 JPG、JPEG 和 PNG 图片,也可能使用懒加载属性保存真实地址。因此程序分别处理了 src、data-src、data-original 等常见属性,并根据 URL 后缀过滤图片类型。通过这次实验,我对网页资源定位、URL 规范化和文件下载流程有了更完整的认识。
作业总结
本次作业分别完成了三类数据采集任务:使用 BeautifulSoup 解析 HTML 表格获取大学排名,使用正则表达式提取商城商品名称和价格,以及提取网页图片链接并保存图片文件。三个任务分别对应结构化文本解析、半结构化商品信息抽取和二进制资源下载。
实验过程中遇到的主要问题包括网页编码、网页结构变化、动态数据载荷以及相对 URL 处理。通过设置请求头、检查响应编码、增加异常处理、使用备用解析方案和规范化 URL,程序的稳定性得到了改善。后续还可以将爬取结果保存为 CSV 或 JSON 文件,并增加日志记录和去重统计功能。
浙公网安备 33010602011771号