视频加载失败

课程

2170 字
约 7 分钟

模块一:网络爬虫与多源数据采集系统 (Web Crawler & Data Extraction)

专业实践与小学期实训2026_0705_Crawler·更新于 2026-09-15

模块一:网络爬虫与多源数据采集系统 (Web Crawler & Data Extraction)

Python Requests lxml BS4 License


📖 模块概述

本模块专注于网络爬虫的核心底层机制与工程化实现,涵盖 HTTP 请求协议交互、反爬伪装机制、多种页面解析技术(XPath、BeautifulSoup4、正则表达式)以及结构化数据存储。通过两个具有代表性的实战项目,完成从文本数据提取持久化计算机视觉数据集采集的完整链路。

graph TD
    A[发起 HTTP 请求] --> B{响应状态校验}
    B -- 成功 200 --> C[响应文本解码 UTF-8 / GBK]
    B -- 失败 / 反爬 --> D[重试策略 / Headers 伪装]
    C --> E[HTML 解析与数据提取]
    E --> F1[XPath 路径表达式]
    E --> F2[BeautifulSoup4 CSS选择器]
    E --> F3[正则表达式 Pattern 匹配]
    F1 --> G1[豆瓣 Top 榜单数据 -> CSV 存储]
    F2 & F3 & F1 --> G2[高清人物/人脸图片 -> 本地文件存储]
    G2 --> H[供后续 YOLOv5 人脸检测使用]

🛠️ 技术栈与核心库

库 / 工具功能描述应用场景
requests优雅而简单的 Python HTTP 库发起 GET 请求、定制 Headers、处理 Session
lxml基于 C 语言的高性能 XML/HTML 解析库使用 XPath 语法高效抽取 DOM 节点信息
bs4 (BeautifulSoup)结构化 HTML/XML 解析工具标签层级导航、CSS 选择器属性提取
rePython 内置正则表达式引擎字符串模式匹配、数字提纯与数据清洗
csvPython 内置标准 CSV 读写模块结构化爬取结果落盘保存

📚 爬虫核心技术要点

1. HTTP 请求与反爬伪装

在发起 HTTP 请求时,许多网站会检测请求头信息(如 User-AgentReferer)以拦截自动化脚本。

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
    "Referer": "https://pic.netbian.com/"
}
Note
  • User-Agent:向服务器声明客户端的操作系统、浏览器内核与版本信息。
  • Referer:防盗链机制的核心字段,表明当前请求是从哪个网页跳转而来的。

2. 解析技术对比

(1) XPath (XML Path Language)

通过路径表达式选取 XML/HTML 文档中的节点。

表达式说明示例
/从根节点选取直接子节点/html/body/div
//选取文档中匹配的任意节点,不考虑位置//div[@class="article"]
@attr选取属性//img/@src
text()提取文本内容//div[@class="title"]/a/text()
contains()包含匹配//div[contains(@class, "item")]

(2) BeautifulSoup4

提供 Pythonic 的文档遍历与搜索方式。

from bs4 import BeautifulSoup

soup = BeautifulSoup(html_content, 'lxml')
# 标签搜索
title_node = soup.find('h1', class_='info')
# CSS 选择器
items = soup.select('div.doulist-item > div.title > a')

(3) 正则表达式 (Regex)

用于高灵活度的文本清洗与提取。

元字符/函数含义
\d+匹配 1 个或多个连续数字(常用于提取评分人数)
re.findall(pattern, string)查找所有匹配项并以列表返回
re.sub(pattern, repl, string)替换匹配内容

💻 实战项目一:豆瓣电影豆单多页抓取与 CSV 导出

1. 业务逻辑

自动化爬取豆瓣精选豆单共 10 页数据(250 条记录),提取电影名称、导演、主演、类型、地区、海报图片链接、评分、评价人数,并导出为标准 UTF-8 格式的 CSV 文件。

2. 核心代码

import csv
import re
import time
import requests
from lxml import html

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
    "Referer": "https://www.douban.com/doulist/3936288/"
}

with open("豆瓣.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.DictWriter(
        f, 
        fieldnames=["电影名称", "导演", "主演", "类型", "地区", "图片路径", "评分", "评价人数"]
    )
    writer.writeheader()
    
    for page in range(1, 11):
        url = f"https://www.douban.com/doulist/3936288/?start={(page - 1) * 25}&sort=time&playable=0&sub_type="
        res = requests.get(url, headers=headers, timeout=10)
        res.encoding = "utf-8"
        
        page_html = html.etree.HTML(res.text)
        divs = page_html.xpath('//div[@class="article"]/div[@class="doulist-item"]')
        
        for div in divs:
            row = {}
            # 提取结构化信息
            msgs = div.xpath('./div//div[@class="abstract"]/text()')
            row["导演"] = msgs[0].strip() if len(msgs) > 0 else ""
            row["主演"] = msgs[1].strip() if len(msgs) > 1 else ""
            row["类型"] = msgs[2].strip() if len(msgs) > 2 else ""
            row["地区"] = msgs[3].strip() if len(msgs) > 3 else ""
            
            img_src = div.xpath('./div//div[@class="post"]/a/img/@src')
            row["图片路径"] = img_src[0] if img_src else ""
            
            score = div.xpath('./div//div[@class="rating"]/span[2]/text()')
            row["评分"] = score[0] if score else "0.0"
            
            comment_count = div.xpath('./div//div[@class="rating"]/span[3]/text()')
            if comment_count:
                nums = re.findall(r'\d+', comment_count[0])
                row["评价人数"] = nums[0] if nums else "0"
            else:
                row["评价人数"] = "0"
                
            title = div.xpath('./div//div[@class="title"]/a/text()')
            row["电影名称"] = "".join(title).strip()
            
            writer.writerow(row)
            
        print(f"✅ 第 {page}/10 页爬取完成")
        time.sleep(2)  # 礼貌爬虫延时,防止触发频控

💻 实战项目二:多页人脸与明星图片自动化抓取

1. 业务逻辑

针对图片壁纸站点,解析分页 URL 规律与图片 DOM 结构,按指定明星分类(如 鞠婧祎, 陈瑶, 迪丽热巴, 王心凌, 白鹿 等)自动按阈值下载高清人脸图片,为模块二的 YOLOv5 目标检测与人脸识别准备训练原始样本。

2. URL 规律分析

  • 第一页:https://pic.netbian.com/4kmeinv/
  • 第二页及以后:https://pic.netbian.com/4kmeinv/index_{page}.html

3. 核心抓取脚本 (paqu_mingxing.py)

import os
import time
import requests
from lxml import html

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
    "Referer": "https://pic.netbian.com/"
}

os.makedirs("mingxing_tupian", exist_ok=True)

targets = {
    "鞠婧祎": "jujingyi",
    "陈瑶": "chenyao",
    "迪丽热巴": "dilireba",
    "王心凌": "wangxinling",
    "白鹿": "bailu"
}

target_counts = {k: 0 for k in targets.values()}
MAX_PER_PERSON = 8

for page in range(1, 46):
    if all(count >= MAX_PER_PERSON for count in target_counts.values()):
        print("🎯 所有目标人物图片均已集齐!")
        break
        
    url = "https://pic.netbian.com/4kmeinv/" if page == 1 else f"https://pic.netbian.com/4kmeinv/index_{page}.html"
    res = requests.get(url, headers=headers, timeout=10)
    page_html = html.etree.HTML(res.content)
    
    img_nodes = page_html.xpath('//ul[@class="clearfix"]/li/a/img')
    for img in img_nodes:
        alt_list = img.xpath('./@alt')
        src_list = img.xpath('./@src')
        if not alt_list or not src_list:
            continue
            
        alt, src = alt_list[0], src_list[0]
        
        for cn_name, en_tag in targets.items():
            if cn_name in alt and target_counts[en_tag] < MAX_PER_PERSON:
                img_url = "https://pic.netbian.com" + src
                img_data = requests.get(img_url, headers=headers, timeout=10).content
                
                save_path = f"mingxing_tupian/{en_tag}_{target_counts[en_tag]}.jpg"
                with open(save_path, "wb") as f:
                    f.write(img_data)
                    
                target_counts[en_tag] += 1
                print(f"📥 下载成功: {save_path} (进度: {target_counts[en_tag]}/{MAX_PER_PERSON})")
                time.sleep(1)
                
    time.sleep(2)

🚀 快速开始与使用指南

1. 安装依赖

pip install -r requirements.txt

2. 运行爬虫

# 1. 运行明星人脸分类抓取
python paqu_mingxing.py

# 2. 运行人脸批量抓取
python paqu_renlian.py
Tip

抓取完成后,生成的高清图片将分别存放于 renlian/mingxing_tupian/ 目录,供下一阶段的 YOLOv5 标注与模型训练使用。


📄 开源许可证

本项目遵循 CC BY-NC-SA 4.0 许可协议开源。

Profile Image of the Author
Sonder
好想要技术
这是公告标题
这只是一个公告
分类
标签
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录