适合零基础的Python实战小项目:爬虫与数据处理入门案例

闻溪
闻溪
发布时间:2026-10-23 | 8人浏览过
原创

如果你刚刚学完 Python 的基础语法(变量、列表、循环和函数),往往会面临不知道能用它做什么的困惑。网络爬虫与数据处理是检验编程基础最直观的方向:你只需要编写几十行代码,就能直接从互联网抓取真实的公开网页数据,完成清理并将它保存为日常使用的表格文件。本文以公开开放的练习站点为抓手,完整走通从发送网络请求、定位网页元素,到脏数据清洗与 CSV 文件持久化的全过程,帮助初学者建立扎实的数据收集与处理链路。

适合零基础的Python实战小项目:爬虫与数据处理入门案例
图1:Python 爬虫与数据清洗落盘全流程架构与数据流向

一、实战目标与环境准备

在开始写代码前,我们先明确本次实战的核心目标。我们选择业界公认的合规爬虫练习靶场 http://books.toscrape.com/ 作为数据源。该站点专为爬虫教学设计,页面结构稳定、无反爬验证码干扰,非常适合用来验证解析与清洗逻辑。

我们需要抓取并处理以下四个核心字段:

  • 完整书名(Title):解决前端页面因排版缩略导致的标题截断问题;
  • 价格(Price):剥离货币符号,转换为可参与数学计算的浮点数(float);
  • 星级评级(Rating):将英文单词(如 One、Three)映射为整数 1 到 5;
  • 库存状况(In Stock):提取并整理是否有货的明确状态。

1. 依赖库安装

本项目仅需两个轻量级第三方库:requests(用于发送网络请求并接收 HTML 内容)和 beautifulsoup4(用于解析 HTML 树结构并提取目标数据)。文件保存使用 Python 自带的 csv 标准库,无需额外安装。

在你的命令行(终端或 PowerShell)中执行以下安装命令:

pip install requests beautifulsoup4
版本与环境确认

建议使用 Python 3.8 及以上版本。安装完成后,可以在命令行输入 python -c "import requests, bs4; print('环境准备就绪')" 进行验证,若输出提示语且无报错,即可进入下一步。

二、发送网络请求与检查响应状态

爬虫的第一步是让程序模仿浏览器的行为,向目标网址发起 HTTP GET 请求,并拿回服务器返回的网页源代码。很多初学者写爬虫最容易遇到的问题是:请求发出了,但拿到的是 403 拒绝访问或空内容。这是因为默认的 Python 请求头没有携带浏览器标识。

通过在请求中添加简单的 headers 参数,指定常见的 User-Agent,可以避免大部分基础的客户端拦截。

import requests

url = "http://books.toscrape.com/catalogue/page-1.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"
}

response = requests.get(url, headers=headers, timeout=10)

if response.status_code == 200:
    print(f"请求成功,获取网页长度:{len(response.text)} 字符")
else:
    print(f"请求失败,HTTP 状态码:{response.status_code}")

当执行上述代码并看到 请求成功 时,说明 response.text 中已经存储了完整的 HTML 文档。接下来我们需要深入文档内部,找到每本书对应的 HTML 标签。

适合零基础的Python实战小项目:爬虫与数据处理入门案例
图2:HTML 树状节点与 BeautifulSoup 元素选择器对应关系

三、解析 HTML 节点与规避常见陷阱

在拿到 response.text 之后,我们使用 BeautifulSoup(response.text, "html.parser") 将其转化为可遍历的 DOM 对象。初学者在定位元素时,最容易踩进两个陷阱:

  1. 书名截断问题:在页面上,长书名通常显示为 A Light in the ...。如果你使用 a.text,提取到的只是不完整的缩略文本。在审查元素时可以发现,完整书名被完整保存在 <a> 标签的 title 属性中。因此应使用 a["title"] 提取属性值。
  2. 多类名(Class)解析:星级评级标签的类名为 star-rating Three。BeautifulSoup 在解析 class 属性时会返回一个列表 ['star-rating', 'Three']。直接提取列表第二个元素即可获取具体的评级英文词汇。
适合零基础的Python实战小项目:爬虫与数据处理入门案例
图3:单本图书元素提取与容错清洗逐步执行流程

四、数据清洗与结构化转换

直接从网页提取出的数据被称为“脏数据”:数字带有货币符号(如 £51.77)、评级是纯英文单词(如 Three)、库存描述包含多余的前后换行与空格。如果直接写入表格,后续将无法进行价格排序、计算平均价格或按评分筛选。

数据清洗的核心任务就是把文本字符串转换成标准类型:

适合零基础的Python实战小项目:爬虫与数据处理入门案例
图4:数据清洗规则与转换映射明细

五、完整实战代码与数据持久化

下面是将网络请求、节点提取、数据清洗与 CSV 存储串联起来的完整可执行代码。我们使用内置的 csv.DictWriter,以字典列表的形式批量写入数据。为了防止在 Windows 系统下的 Excel 打开 CSV 时出现中文乱码,我们显式指定编码格式为 utf-8-sig。

import csv
import requests
from bs4 import BeautifulSoup

def clean_price(price_str):
    """剔除货币符号并转换为浮点数"""
    clean_str = price_str.replace("£", "").replace("Â", "").strip()
    try:
        return float(clean_str)
    except ValueError:
        return 0.0

def clean_rating(rating_class_list):
    """将英文评分映射为对应的整数 1-5"""
    rating_map = {
        "One": 1,
        "Two": 2,
        "Three": 3,
        "Four": 4,
        "Five": 5
    }
    for item in rating_class_list:
        if item in rating_map:
            return rating_map[item]
    return 0

def scrape_books(target_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(target_url, headers=headers, timeout=10)
    response.encoding = "utf-8"
    
    if response.status_code != 200:
        print(f"请求失败,状态码: {response.status_code}")
        return []

    soup = BeautifulSoup(response.text, "html.parser")
    book_pods = soup.find_all("article", class_="product_pod")
    
    books_data = []
    for pod in book_pods:
        # 1. 提取完整书名
        a_tag = pod.find("h3").find("a")
        title = a_tag.get("title", a_tag.text.strip())
        
        # 2. 提取并清洗价格
        raw_price = pod.find("p", class_="price_color").text
        price = clean_price(raw_price)
        
        # 3. 提取并映射星级
        rating_tag = pod.find("p", class_="star-rating")
        rating_classes = rating_tag.get("class", [])
        rating = clean_rating(rating_classes)
        
        # 4. 提取库存状态
        stock_text = pod.find("p", class_="instock").text.strip()
        in_stock = "有货" if "In stock" in stock_text else "缺货"
        
        books_data.append({
            "书名": title,
            "价格(英镑)": price,
            "星级评级": rating,
            "库存状态": in_stock
        })
        
    return books_data

def save_to_csv(data_list, output_filename="books.csv"):
    """将数据安全保存为 UTF-8-SIG 编码的 CSV 文件"""
    if not data_list:
        print("未获取到有效数据,跳过保存。")
        return

    fieldnames = ["书名", "价格(英镑)", "星级评级", "库存状态"]
    with open(output_filename, mode="w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(data_list)
        
    print(f"数据已成功保存至 {output_filename},共计 {len(data_list)} 条记录。")

if __name__ == "__main__":
    target_page = "http://books.toscrape.com/catalogue/page-1.html"
    print("开始抓取图书数据...")
    scraped_data = scrape_books(target_page)
    save_to_csv(scraped_data, "books.csv")

运行结果与示例输出

在安装好依赖的环境中直接运行该脚本,终端将输出:

开始抓取图书数据...
数据已成功保存至 books.csv,共计 20 条记录。

在脚本同目录下会生成名为 books.csv 的文件。使用 Excel 或文本编辑器打开,其内容示例如下:

书名 价格(英镑) 星级评级 库存状态
A Light in the Attic 51.77 3 有货
Tipping the Velvet 53.74 1 有货
Soumission 50.10 1 有货
Sharp Objects 47.82 4 有货
Sapiens: A Brief History of Humankind 54.23 5 有货

六、零基础避坑与进阶指引

完成单页抓取与存储后,你在向多页爬虫或更复杂项目扩展时,需要注意以下常见问题:

  • AttributeError: 'NoneType' object has no attribute 'text':这是初学爬虫最频繁遇到的报错。原因在于页面上某些卡片缺失特定元素,find() 返回了 None,对其调用 .text 时程序崩溃。建议始终对可能缺失的标签进行非空判断或封装带有 try-except 的提取辅助函数。
  • 分页 URL 的生成规律:观察第二页、第三页的地址,例如 catalogue/page-2.html。你可以利用 Python 的 f-string(例如 f"http://books.toscrape.com/catalogue/page-{page}.html")写一个简单的 for page in range(1, 6): 循环,轻松实现抓取前 5 页的 100 本图书。
  • 请求礼貌与抓取间隔:当抓取多页数据时,必须在每次循环中导入 time 模块并调用 time.sleep(1),主动在请求之间停顿 1 秒左右。这不仅是网络爬虫的道德准则,也能有效防止因并发过高而被对端服务器临时拉黑 IP。
适合零基础的Python实战小项目:爬虫与数据处理入门案例
图5:零基础爬虫与数据处理体系结构与进阶路线闭环总结

七、总结

通过这个小项目,我们不仅掌握了 requests 和 BeautifulSoup 的核心语法,更重要的是建立了一套严谨的数据处理思维:网络数据并非“抓下来就算完成”,它必然经历网络请求拦截防御、精准 DOM 节点寻址、字段类型转换清洗以及最终的规范化持久存储。掌握这一完整的闭环流程后,无论面对何种类型的公开静态网页,你都能从容设计出稳定可靠的自动化数据采集脚本。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表