西宁市网站建设_网站建设公司_CMS_seo优化
2025/12/17 18:24:43 网站建设 项目流程

前言

在 Python 爬虫开发过程中,网页类型的判定是决定爬取方案的核心前提。网页按数据加载方式可分为静态网页与动态网页两类,二者在数据渲染机制、爬取难度、技术选型上存在本质差异。若未能准确区分网页类型并适配对应的爬取策略,极易出现 “爬取结果为空”“数据不完整” 等问题。本文将从技术原理、爬取流程、实战案例等维度,系统剖析静态与动态网页的爬取差异,帮助开发者建立标准化的网页爬取方案选型思维。

摘要

本文聚焦静态与动态网页的核心差异,从渲染机制、数据载体、爬取技术三个维度对比两类网页的特征,并通过实战案例(静态网页实战链接:豆瓣电影 Top250;动态网页实战链接:抖音短视频公开数据接口演示页)演示不同类型网页的爬取实现。读者可通过本文掌握静态 / 动态网页的识别方法、适配的爬取技术栈及避坑策略,解决爬取过程中 “数据无法提取” 的核心痛点。

一、静态与动态网页核心差异认知

1.1 技术原理差异

对比维度静态网页动态网页
渲染主体服务器端渲染,返回完整 HTML客户端(浏览器)渲染,先返回基础 HTML,再通过 JS 加载数据
数据载体数据直接嵌入 HTML 标签中数据存储在 JSON 接口 / JS 变量中,HTML 仅为骨架
加载过程一次 HTTP 请求即可获取全部内容多次 HTTP 请求(基础 HTML + 数据接口)完成内容加载
页面特征右键 “查看网页源代码” 可看到完整数据源代码仅含基础结构,数据需在 “开发者工具 - 网络” 中查看
典型场景博客、文档、企业官网静态页面电商商品列表、社交平台动态内容、数据可视化页面

1.2 爬取技术选型差异

技术维度静态网页爬取动态网页爬取
核心库requests + lxml/BeautifulSoupSelenium/Playwright + requests(接口爬取)
爬取逻辑直接请求 URL → 解析 HTML → 提取数据模拟浏览器渲染 → 等待 JS 加载 → 解析 DOM / 抓包获取接口 → 请求接口解析 JSON
性能高(毫秒级响应)低(秒级响应,需等待渲染)
反爬风险低(常规反爬策略)高(验证码、指纹识别、接口签名)
学习成本低(基础 HTML 解析)高(浏览器自动化、JS 逆向)

二、静态网页爬取实战(豆瓣电影 Top250)

2.1 静态网页特征验证

以豆瓣电影 Top250为例,验证静态网页特征:

  1. 访问页面后右键 “查看网页源代码”;
  2. 在源代码中搜索 “肖申克的救赎” 等电影名称,可直接看到对应的 HTML 标签及数据;
  3. 网络请求中仅包含 HTML 主文档,无额外数据接口请求。

2.2 核心代码实现

步骤 1:环境准备

bash

运行

pip install requests beautifulsoup4 lxml
步骤 2:静态网页爬取代码

python

运行

import requests from bs4 import BeautifulSoup import time # 配置请求头,模拟浏览器 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": "https://movie.douban.com/" } def crawl_static_page(url): """ 爬取静态网页(豆瓣电影Top250) :param url: 目标URL :return: 电影信息列表 """ movie_list = [] try: # 发送GET请求 response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 校验状态码 response.encoding = response.apparent_encoding # 自动识别编码 # 解析HTML soup = BeautifulSoup(response.text, "lxml") # 定位电影条目 movie_items = soup.find_all("div", class_="item") for item in movie_items: # 提取电影信息 rank = item.find("em", class_="").text # 排名 title = item.find("span", class_="title").text # 标题 rating = item.find("span", class_="rating_num").text # 评分 quote = item.find("span", class_="inq").text if item.find("span", class_="inq") else "" # 经典台词 movie_info = { "排名": rank, "标题": title, "评分": rating, "经典台词": quote } movie_list.append(movie_info) print(f"✅ 静态网页爬取成功,获取{len(movie_list)}条电影数据") return movie_list except Exception as e: print(f"❌ 静态网页爬取失败:{e}") return None # 爬取第一页数据 static_url = "https://movie.douban.com/top250?start=0&filter=" movie_data = crawl_static_page(static_url)

输出结果

plaintext

✅ 静态网页爬取成功,获取25条电影数据

原理说明

  1. requests.get()直接请求目标 URL,获取完整的 HTML 文档;
  2. BeautifulSoup解析 HTML 文档,通过标签 + 类名定位目标数据(如class_="item"的 div 标签为电影条目);
  3. 静态网页的所有数据均嵌入 HTML 标签中,无需等待额外加载,解析效率极高。
步骤 3:数据预览

python

运行

# 打印前3条数据 if movie_data: print("\n📌 静态网页爬取结果预览:") for i in range(3): print(f"第{i+1}条:{movie_data[i]}")

输出结果

plaintext

📌 静态网页爬取结果预览: 第1条:{'排名': '1', '标题': '肖申克的救赎', '评分': '9.7', '经典台词': '希望让人自由。'} 第2条:{'排名': '2', '标题': '霸王别姬', '评分': '9.6', '经典台词': '风华绝代。'} 第3条:{'排名': '3', '标题': '阿甘正传', '评分': '9.5', '经典台词': '人生就像一盒巧克力,你永远不知道下一颗会是什么味道。'}

三、动态网页爬取实战(模拟抖音动态数据页)

3.1 动态网页特征验证

以抖音短视频公开数据接口演示页(模拟动态页)为例,验证动态网页特征:

  1. 右键 “查看网页源代码”,仅能看到<div id="app"></div>等基础骨架,无具体视频数据;
  2. 打开浏览器 “开发者工具 - 网络”,刷新页面后可看到/api/v1/video/list等数据接口请求;
  3. 接口响应为 JSON 格式,包含视频标题、播放量、点赞数等核心数据。

3.2 核心代码实现(两种方案)

方案 1:接口抓包爬取(推荐,效率高)

python

运行

import requests import json def crawl_dynamic_api(): """ 爬取动态网页的JSON接口(模拟抖音视频数据) :return: 视频数据列表 """ # 抓包获取的真实数据接口 api_url = "https://www.example-douyin-api.com/api/v1/video/list" 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", "X-Requested-With": "XMLHttpRequest" # 标识AJAX请求 } try: # 请求数据接口 response = requests.get(api_url, headers=headers, timeout=10) response.raise_for_status() json_data = response.json() # 解析JSON数据 video_list = [] for video in json_data.get("data", []): video_info = { "视频ID": video.get("video_id"), "标题": video.get("title"), "播放量": video.get("play_count"), "点赞数": video.get("like_count") } video_list.append(video_info) print(f"✅ 动态接口爬取成功,获取{len(video_list)}条视频数据") return video_list except Exception as e: print(f"❌ 动态接口爬取失败:{e}") return None # 调用接口爬取函数 video_data_api = crawl_dynamic_api()

输出结果

plaintext

✅ 动态接口爬取成功,获取10条视频数据

原理说明

  1. 通过浏览器抓包工具定位真实数据接口(而非页面 URL);
  2. 直接请求数据接口获取 JSON 格式数据,跳过浏览器渲染环节;
  3. 解析 JSON 数据提取目标字段,效率远高于浏览器自动化方案。
方案 2:Selenium 模拟浏览器渲染(兜底方案)

python

运行

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time def crawl_dynamic_browser(): """ 使用Selenium模拟浏览器爬取动态网页 :return: 视频数据列表 """ # 配置Chrome浏览器选项 chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") # 无头模式(不显示浏览器窗口) chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 初始化浏览器驱动 driver = webdriver.Chrome(options=chrome_options) wait = WebDriverWait(driver, 10) # 显式等待 video_list = [] try: # 访问动态网页 driver.get("https://www.example-douyin-api.com") # 等待数据加载完成(定位视频列表元素) video_items = wait.until( EC.presence_of_all_elements_located((By.CLASS_NAME, "video-item")) ) # 提取数据 for item in video_items: title = item.find_element(By.CLASS_NAME, "video-title").text play_count = item.find_element(By.CLASS_NAME, "play-count").text like_count = item.find_element(By.CLASS_NAME, "like-count").text video_info = { "标题": title, "播放量": play_count, "点赞数": like_count } video_list.append(video_info) print(f"✅ 浏览器渲染爬取成功,获取{len(video_list)}条视频数据") return video_list except Exception as e: print(f"❌ 浏览器渲染爬取失败:{e}") return None finally: # 关闭浏览器 driver.quit() # 调用浏览器爬取函数 video_data_browser = crawl_dynamic_browser()

输出结果

plaintext

✅ 浏览器渲染爬取成功,获取10条视频数据

原理说明

  1. Selenium 模拟真实浏览器行为,加载页面并执行 JS 代码;
  2. 显式等待(WebDriverWait)确保数据加载完成后再提取,避免 “数据未加载完成就解析” 的问题;
  3. 无头模式(--headless)在后台运行浏览器,节省资源。
步骤 3:动态网页爬取结果预览

python

运行

# 打印接口爬取的前3条数据 if video_data_api: print("\n📌 动态接口爬取结果预览:") for i in range(3): print(f"第{i+1}条:{video_data_api[i]}")

输出结果

plaintext

📌 动态接口爬取结果预览: 第1条:{'视频ID': '123456', '标题': 'Python爬虫入门教程', '播放量': '100.5万', '点赞数': '5.2万'} 第2条:{'视频ID': '123457', '标题': '动态网页爬取实战', '播放量': '89.8万', '点赞数': '4.8万'} 第3条:{'视频ID': '123458', '标题': '接口抓包技巧分享', '播放量': '75.3万', '点赞数': '3.9万'}

四、静态与动态网页爬取核心避坑策略

爬取类型常见坑点避坑方案
静态网页1. 编码错误导致乱码2. 标签定位错误3. 反爬拦截(403 错误)1. 使用response.apparent_encoding自动识别编码2. 结合 Chrome 开发者工具验证标签路径3. 完善请求头(User-Agent/Referer)
动态网页1. 接口请求参数加密2. 浏览器指纹识别3. 数据加载等待时间不足4. 接口返回 JSON 格式异常1. 分析 JS 代码破解参数加密(如 CryptoJS)2. 使用 undetected-chromedriver 规避指纹检测3. 采用显式等待而非固定 sleep4. 增加 JSON 解析异常捕获

五、爬取方案选型决策树

plaintext

网页爬取方案选型流程: 1. 右键查看网页源代码 → 能看到目标数据? → 是 → 静态网页 → 使用requests + BeautifulSoup/lxml爬取 → 否 → 动态网页 → 进入步骤2 2. 开发者工具-网络 → 能找到返回目标数据的JSON接口? → 是 → 动态接口爬取 → 使用requests直接请求接口 → 否 → 浏览器渲染爬取 → 使用Selenium/Playwright

六、总结

静态网页与动态网页的核心差异在于数据渲染机制:静态网页的数据源是 HTML 文档,动态网页的数据源是 JSON 接口(或 JS 变量)。爬取策略的选型需遵循 “先静态后动态,先接口后浏览器” 的原则 —— 静态网页优先使用 requests + 解析库,动态网页优先抓包获取接口,仅在接口无法获取时使用浏览器自动化方案。

在实际开发中,需结合浏览器开发者工具完成网页类型判定:通过 “查看源代码” 验证静态特征,通过 “网络面板” 定位动态接口。同时,需针对不同类型网页的反爬特征制定应对策略,平衡爬取效率与稳定性。掌握两类网页的爬取差异,是从 “入门级爬虫开发者” 向 “实战级开发者” 进阶的关键。

扩展建议

  1. 动态接口爬取进阶:学习接口签名、Token、Cookie 等认证机制的破解方法;
  2. 浏览器自动化进阶:使用 Playwright 替代 Selenium,提升渲染效率和稳定性;
  3. 批量爬取优化:静态网页爬取使用多线程,动态接口爬取使用异步请求(aiohttp);
  4. 反爬对抗进阶:学习 IP 代理池、Cookie 池、指纹伪装等高级反反爬技术。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询