一、前置准备

1. Python 环境安装(Windows)

  • 下载 3.10 + 版本,必须勾选 Add Python to PATH(核心关键,否则命令行无法识别 Python),一键完成安装。

  • 验证方式:打开 cmd,输入python --version/pip --version,输出版本号即安装成功。

2. 核心库安装(一行命令)

bash

运行

# 基础三件套:请求、解析、数据存储,覆盖90%基础爬取需求
pip install requests beautifulsoup4 pandas
# 国内镜像源(解决网络卡顿/安装失败问题)
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 可选:动态页面解析库(进阶用)
pip install playwright
playwright install chromium  # 安装浏览器内核

3. 核心工具:浏览器 F12 开发者工具

  • 操作流程:打开目标网页 → 按 F12 / 右键「检查」 → 点击左上角箭头图标 → 鼠标定位网页内容,自动匹配对应 HTML 代码(确定数据所在位置)。

  • 关键技巧:定位元素后,右键代码→Copy→Copy selector,可直接获取 CSS 选择器,避免手动编写出错。

二、4 个核心实战案例(可直接运行)

案例 1:爬取网页标题(最简入门)

python

运行

import requests
from bs4 import BeautifulSoup

# 仅需修改目标URL
url = "https://www.example.com"
# 伪装浏览器请求头(必加,防403错误)
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()  # 触发4xx/5xx HTTP错误
except Exception as e:
    print(f"爬取失败:{e}")
else:
    # 解析并提取标题
    soup = BeautifulSoup(response.text, "lxml")
    title = soup.title.string
    print(f"网页标题:{title}")
    # 保存结果(指定utf-8编码防乱码)
    with open("网页标题.txt", "w", encoding="utf-8") as f:
        f.write(title)

案例 2:爬取免费小说章节内容

python

运行

import requests
from bs4 import BeautifulSoup

# 替换为目标小说章节URL
chapter_url = "https://www.example-novel.com/chapter/123.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:
    response = requests.get(chapter_url, headers=headers)
    response.encoding = response.apparent_encoding
    response.raise_for_status()
except Exception as e:
    print(f"爬取失败:{e}")
else:
    soup = BeautifulSoup(response.text, "lxml")
    # 用F12定位的选择器提取内容(需根据实际网页调整)
    chapter_title = soup.select_one("h1.chapter-title").text
    chapter_content = soup.select_one("div.chapter-content").text
    # 清理冗余格式,提升阅读体验
    chapter_content = chapter_content.replace(" ", "").replace("\n\n", "\n")
    # 按章节名保存文件
    with open(f"{chapter_title}.txt", "w", encoding="utf-8") as f:
        f.write(chapter_title + "\n\n" + chapter_content)

案例 3:爬取豆瓣电影 TOP250(分页 + CSV 保存)

python

运行

import requests
from bs4 import BeautifulSoup
import pandas as pd

# 分页URL模板:start=0(第1页)、start=25(第2页)
base_url = "https://movie.douban.com/top250?start={}&filter="
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"}
all_movies = []  # 存储所有爬取数据

# 爬取前2页,range(起始, 结束, 步长)
for page in range(0, 50, 25):
    url = base_url.format(page)
    try:
        response = requests.get(url, headers=headers)
        response.encoding = response.apparent_encoding
        response.raise_for_status()
    except Exception as e:
        print(f"第{page//25 + 1}页爬取失败:{e}")
        continue
    # 解析页面数据
    soup = BeautifulSoup(response.text, "lxml")
    for item in soup.select("li.item"):
        all_movies.append({
            "电影名称": item.select_one("span.title").text,
            "评分": item.select_one("span.rating_num").text
        })

# 保存为CSV(utf-8-sig解决Excel打开中文乱码)
if all_movies:
    df = pd.DataFrame(all_movies)
    df.to_csv("豆瓣TOP250.csv", index=False, encoding="utf-8-sig")
    print(f"共爬取{len(all_movies)}条数据,已保存至豆瓣TOP250.csv")

案例 4:进阶:爬取动态加载内容(Playwright)

python

运行

from playwright.sync_api import sync_playwright
import pandas as pd

all_data = []
# 启动无头浏览器(headless=True为无界面模式)
with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.set_extra_http_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"})
    # 访问页面,等待网络空闲(确保动态内容加载完成)
    page.goto("https://www.example.com/dynamic", wait_until="networkidle")
    
    # 提取动态加载的列表数据
    items = page.locator("div.dynamic-item").all()
    for item in items:
        title = item.locator("h3").inner_text()
        price = item.locator("span.price").inner_text()
        all_data.append({"标题": title, "价格": price})
    
    browser.close()

# 保存数据
if all_data:
    pd.DataFrame(all_data).to_csv("动态数据.csv", index=False, encoding="utf-8-sig")

三、基础必避 5 大坑

  1. 中文乱码:网页编码与保存编码不一致 → 请求后添加response.encoding = response.apparent_encoding;保存文本用encoding="utf-8",保存 CSV 用encoding="utf-8-sig"

  2. 爬不到数据:CSS 选择器错误 / 页面动态加载 → 用 F12 重新核对选择器;静态页面爬取失败时,优先排查选择器,动态页面改用 Playwright。

  3. 403 请求被拒:未伪装浏览器身份 → headers 必须包含User-Agent,必要时可添加Referer(来源页)、Accept-Language等字段。

  4. 程序闪退:无异常处理机制 → 所有网络请求代码放入try...except块,捕获并打印异常。

  5. pip 安装库失败:网络 / 源的问题 → 切换国内镜像源;若提示权限不足,添加--user(如pip install requests --user)。

四、4 个实用优化技巧

1. 防反爬:可控爬取频率

python

运行

import time, random
# 固定延迟(基础版)
time.sleep(1)
# 随机延迟(进阶版,更贴近真人操作)
delay = random.uniform(1, 3)
time.sleep(delay)
# 批量爬取时,每爬10页增加一次长延迟
if page % 10 == 0:
    time.sleep(5)

2. 日志记录(替代 print,便于排查问题)

python

运行

import logging
# 配置日志:同时输出到控制台和文件
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s",
    handlers=[
        logging.FileHandler("爬虫日志.log", encoding="utf-8"),
        logging.StreamHandler()
    ]
)
# 使用示例
logging.info("开始爬取第1页数据")
logging.error(f"第{page}页爬取失败:{e}")

3. 数据去重(避免分页 / 重复请求导致的数据冗余)

python

运行

# 基于关键字段去重(如电影名称)
seen_titles = set()
unique_data = []
for item in all_movies:
    if item["电影名称"] not in seen_titles:
        seen_titles.add(item["电影名称"])
        unique_data.append(item)

4. 断点续爬(避免重复爬取已完成内容)

python

运行

import os
import pandas as pd

# 检查是否有已保存的临时文件
temp_file = "临时数据.csv"
if os.path.exists(temp_file):
    # 读取已爬取数据
    all_movies = pd.read_csv(temp_file, encoding="utf-8-sig").to_dict("records")
    # 计算已爬取页数,从下一页开始
    start_page = len(all_movies) // 25 * 25
else:
    all_movies = []
    start_page = 0

# 继续爬取(从start_page开始)
for page in range(start_page, 50, 25):
    # 爬取逻辑(同案例3)
    # ...
    # 每爬完一页保存临时数据
    pd.DataFrame(all_movies).to_csv(temp_file, index=False, encoding="utf-8-sig")

五、爬虫安全守则

  1. 合规为先:爬取前查看目标网站的robots.txt文件(如https://www.example.com/robots.txt),严格遵守其爬取规则;禁止爬取Disallow字段指定的内容。

  2. 版权保护:仅爬取免费、公开的非商业内容,爬取数据仅限个人学习使用;商业用途必须获得网站方书面授权,禁止擅自传播、售卖爬取的数据。

  3. 控制负载:设置合理的爬取延迟(至少 1 秒 / 次),禁止高频、批量请求给服务器造成压力;禁止使用爬虫从事 DDoS 攻击等恶意行为。

  4. 身份合规:禁止伪造 IP、篡改请求头等恶意伪装行为;若网站要求登录,需使用合法账号,禁止暴力破解、盗用他人账号。

  5. 数据合规:禁止爬取个人信息(手机号、身份证、住址等)、隐私数据、敏感商业数据;爬取到无关隐私数据时需立即删除,不得留存。

  6. 法律边界:遵守《网络安全法》《数据安全法》《个人信息保护法》等法律法规,禁止爬取国家机关、金融、医疗等敏感领域网站数据;若收到网站停止爬取的通知,需立即终止操作。

  7. 责任自负:爬虫行为导致的法律责任、服务器封禁、数据泄露等后果,由使用者自行承担;建议在爬取前评估风险,避免触碰法律红线。