作业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()

结果展示

屏幕截图 2026-10-20 202532
屏幕截图 2026-10-20 202545

心得体会

首先,我认识到“伪装”的重要性。通过在 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. 提取价格:当当网现价通常用 &yen; (即 ¥),用 [¥&yen;]+ 兼容两种情况
            price_match = re.search(r'<span class="price_n">\s*(?:&yen;|¥)\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("书包")

结果展示

屏幕截图 2026-10-20 205155

心得体会

起初我尝试用 requests 爬取京东,却发现现实远比课本复杂。京东拥有极严的反爬机制,直接请求只能拿到“验证拦截页”;即使通过F12抓包复制了 Cookie 绕过验证,拿到的网页源码里也根本没有商品数据,因为商品价格和详情是由 JavaScript 动态渲染的。这让我深刻认识到静态请求的局限性。
为了完成用 re 库提取数据的要求,我果断调整策略,转向了结构更传统、对静态爬虫更友好的当当网。在这个过程中,我熟练掌握了正则表达式的高级用法:用

  • 切割出商品块,用 title="([^"]+)" 精准提取避开高亮标签的商品名,并用 ¥ 兼容提取现价。同时,当当网的中文乱码让我记住了必须显式指定 encoding = 'gbk'。
    这次“一波三折”的实践让我明白:爬虫不是一套代码走天下,而是与网站风控的博弈。只有学会通过 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()
    

    结果展示

    屏幕截图 2026-10-20 202024
    屏幕截图 2026-10-20 202219

    心得体会

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

  • posted on 2026-10-20 21:18  asakinza  阅读(5)  评论(0)    收藏  举报