数据采集第一次作业

第一次实验作业

作业①

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)

结果如下:

1

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

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)

结果如下:

3

3

2):心得体会

通过本次图片爬取作业,我学会了批量下载网络二进制资源的方法,掌握了urljoin函数将相对路径转换为绝对 URL 的技巧,以及os模块对本地文件、文件夹的创建与路径操作,理解了图片文件需要以二进制模式写入的原理,也学会了通过后缀名过滤目标资源的方法

调试中我遇到了图片 URL 携带参数、相对路径解析错误、单张图片超时导致程序中断等问题,通过逐一排查并添加异常处理解决了问题,加深了对 URL 组成结构的理解

posted @ 2026-10-20 17:40  麓川茴  阅读(4)  评论(0)    收藏  举报