Python 爬虫实战:从入门到精通,爬取某站数据

前言

在大数据时代,数据采集是数据分析、人工智能、商业决策的基础环节。Python 凭借简洁的语法、丰富的第三方库,成为爬虫开发的首选语言。但对于大多数初学者而言,往往停留在静态网页爬取阶段,面对当下网站普遍存在的异步加载、参数加密、IP 限制、签名校验等反爬机制时,常常束手无策。

本文将以真实网站数据爬取为实战目标,遵循「零基础入门 → 环境搭建 → 静态爬取 → 动态接口分析 → JS 逆向加密 → 完整爬虫实现 → 反爬绕过 → 数据存储」的完整路径,由浅入深、从理论到实战,带你真正实现 Python 爬虫从入门到精通。全文包含详细原理、逐行注释代码、常见报错解决方案,可直接复制运行,兼顾新手入门与进阶提升。

重要声明:本文仅用于网络爬虫技术学习与交流,严格遵守《网络安全法》《数据安全法》等法律法规,遵守网站 robots 协议。严禁将本文技术用于非法爬取、商业牟利、侵犯他人数据权益、破坏网站正常运行等违法违规行为,一切违规使用后果自负。

一、爬虫前置基础认知

1.1 什么是网络爬虫

网络爬虫又称为网页蜘蛛、网络机器人,是一种按照一定规则,自动抓取互联网信息的程序或脚本。简单来说,就是模拟浏览器发送请求,获取网页数据并进行提取、清洗、存储的自动化工具。

1.2 爬虫能做什么

  • 数据采集:新闻资讯、商品价格、行业数据、论坛帖子等;
  • 数据分析:为机器学习、深度学习提供数据集;
  • 自动化办公:批量下载文件、自动填报、自动抓取报表;
  • 行业监测:竞品数据跟踪、舆情监控、价格监控;
  • 搜索引擎:百度、谷歌等均依靠大规模爬虫实现数据收录。

1.3 爬虫分类

  1. 静态爬虫:爬取纯 HTML 页面,数据直接写在网页源码中,无加密、无异步加载;
  2. 动态爬虫:针对 Ajax、Fetch 异步加载接口,需要分析接口参数;
  3. 逆向爬虫:破解前端 JS 加密、参数签名、数据加密等反爬逻辑;
  4. 模拟浏览器爬虫:使用 Selenium、Playwright 完全模拟人操作浏览器。

1.4 必须了解的 HTTP 基础

  • 请求方法:GET(获取数据)、POST(提交数据);
  • 请求头:User-Agent、Referer、Origin、Cookie 等校验信息;
  • 响应状态码:200 成功、403 禁止访问、404 页面不存在、500 服务器错误;
  • 常见数据格式:HTML、JSON、XML、密文数据。

二、开发环境完整搭建

2.1 Python 环境安装

推荐使用 Python 3.8~3.11 版本,兼容绝大多数爬虫库,避免版本过高导致库不支持。安装时勾选 Add Python to PATH,自动配置环境变量。

验证安装:

bash

运行

复制代码
python --version
pip --version

2.2 爬虫核心第三方库安装

打开 CMD 执行以下命令,使用清华镜像加速安装:

bash

运行

复制代码
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install beautifulsoup4 lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pyexecjs -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install fake-useragent -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple

2.3 Node.js 环境安装

JS 逆向需要执行前端加密代码,依赖 Node.js 环境。下载地址:https://nodejs.org/ 安装 LTS 版本。

验证安装:

bash

运行

复制代码
node -v
npm -v

安装 crypto-js 用于加密算法:

bash

运行

复制代码
npm install crypto-js

2.4 抓包工具准备

使用 Chrome 浏览器自带开发者工具,快捷键 F12 或 Ctrl+Shift+I。核心面板:

  • Element:查看网页结构;
  • Network:抓包分析接口;
  • Source:查看前端 JS 代码;
  • Console:调试 JS 代码。

三、入门阶段:静态网页爬虫实战

静态网页数据直接存在 HTML 中,无需处理加密与异步,适合新手入门。

3.1 静态爬虫核心流程

  1. 构造请求头,模拟浏览器访问;
  2. 发送 GET 请求,获取网页源码;
  3. 使用 BeautifulSoup 解析 HTML;
  4. 提取标题、链接、时间等目标数据;
  5. 数据清洗与简单存储。

3.2 完整静态爬虫代码

python

运行

复制代码
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import time

# 随机请求头
ua = UserAgent()
headers = {
    "User-Agent": ua.random,
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Connection": "keep-alive"
}

def static_spider(url):
    try:
        # 发送请求
        resp = requests.get(url, headers=headers, timeout=10)
        if resp.status_code != 200:
            print(f"请求失败,状态码:{resp.status_code}")
            return []
        
        # 编码处理,解决乱码
        resp.encoding = resp.apparent_encoding
        soup = BeautifulSoup(resp.text, "lxml")
        
        # 数据存储列表
        data_list = []
        
        # 示例提取规则(根据实际页面修改)
        items = soup.find_all("div", class_="list-item")
        for item in items:
            title = item.find("a").get_text(strip=True)
            link = item.find("a")["href"]
            publish_time = item.find("span", class_="time").get_text(strip=True)
            
            data = {
                "标题": title,
                "链接": link,
                "发布时间": publish_time
            }
            data_list.append(data)
        
        return data_list
    
    except Exception as e:
        print(f"爬取异常:{str(e)}")
        return []

if __name__ == "__main__":
    target_url = "https://xxx.xxx.com/news"  # 替换为目标静态地址
    result = static_spider(target_url)
    for i, item in enumerate(result, 1):
        print(i, item)

3.3 静态爬虫局限性

  • 无法获取异步加载数据;
  • 无法处理加密参数与加密数据;
  • 容易被基础反爬识别,无 IP 防护、无签名机制。

想要爬取主流网站,必须进入动态接口与逆向阶段。

四、进阶阶段:动态接口抓包分析

现代网站 90% 数据通过接口异步加载,数据不在 HTML 中,而是通过 JSON 返回。

4.1 抓包步骤

  1. 打开目标网站 → F12 → Network;
  2. 勾选 Preserve log、筛选 XHR/Fetch;
  3. 刷新页面或翻页,查看出现的接口;
  4. 查看接口 URL、请求方法、参数、响应。

4.2 典型加密接口结构

接口地址https://api.xxx.com/api/v1/data/list请求方式 :POST请求参数

json

复制代码
{
    "page": 1,
    "size": 20,
    "timestamp": 1743000000,
    "nonce": "x927s1",
    "sign": "7a2f9d4e8b1c3e5f0a6b7d8c9e0f1a2b"
}

响应内容

json

复制代码
{
    "code": 0,
    "msg": "success",
    "data": "加密字符串一串"
}

4.3 反爬特征分析

  • timestamp:时间戳,防止旧请求重复使用;
  • nonce:随机字符串,防止请求重复;
  • sign:签名,核心加密参数;
  • data:返回密文,需 AES 等方式解密。

直接请求会返回:签名错误、参数非法、请求过期、无权限。

五、精通阶段:JS 逆向破解加密

JS 逆向是爬虫高薪核心技能,本质是找到前端加密逻辑,用 Python 还原。

5.1 定位加密 JS 代码

  1. 在 Network 面板 Ctrl+F 搜索 signencryptmd5aes
  2. 在 Source 面板查找混淆 / 压缩的 JS 文件;
  3. 使用断点调试,查看参数生成过程。

5.2 典型加密逻辑(真实通用)

javascript

运行

复制代码
// 生成签名
function makeSign(page, timestamp, nonce){
    let key = "spider123456abcdef";
    let str = `page=${page}&t=${timestamp}&nonce=${nonce}&key=${key}`;
    return md5(str);
}

// 随机字符串
function nonceStr(){
    let chars = "0123456789abcdef";
    let res = "";
    for(let i=0;i<6;i++){
        res += chars[Math.floor(Math.random()*chars.length)]
    }
    return res;
}

// AES解密
function decrypt(data){
    let key = CryptoJS.enc.Utf8.parse("1234567890123456");
    let iv = CryptoJS.enc.Utf8.parse("abcdef1234567890");
    let decrypted = CryptoJS.AES.decrypt(data, key, {
        iv:iv,
        mode:CryptoJS.mode.CBC,
        padding:CryptoJS.pad.Pkcs7
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
}

六、终极实战:完整逆向爬虫(可直接运行)

整合所有技术,实现可落地的加密接口爬虫。

6.1 完整源码

python

运行

复制代码
# -*- coding: utf-8 -*-
import execjs
import requests
import time
import json
import pandas as pd
from fake_useragent import UserAgent

# ==================== JS 加密代码 ====================
js_code = """
const CryptoJS = require('crypto-js');

function makeSign(page, timestamp, nonce){
    let key = "spider123456abcdef";
    let str = `page=${page}&t=${timestamp}&nonce=${nonce}&key=${key}`;
    return CryptoJS.MD5(str).toString();
}

function nonceStr(){
    let chars = "0123456789abcdef";
    let res = "";
    for(let i=0;i<6;i++){
        res += chars[Math.floor(Math.random()*chars.length)]
    }
    return res;
}

function decrypt(data){
    let key = CryptoJS.enc.Utf8.parse("1234567890123456");
    let iv = CryptoJS.enc.Utf8.parse("abcdef1234567890");
    let decrypted = CryptoJS.AES.decrypt(data, key, {
        iv:iv,
        mode:CryptoJS.mode.CBC,
        padding:CryptoJS.pad.Pkcs7
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
}
"""

# ==================== 初始化环境 ====================
ctx = execjs.compile(js_code)
ua = UserAgent()

headers = {
    "User-Agent": ua.random,
    "Content-Type": "application/json;charset=UTF-8",
    "Origin": "https://xxx.com",
    "Referer": "https://xxx.com/",
    "Accept": "application/json, text/plain, */*"
}

# 目标接口
api = "https://api.xxx.com/api/v1/data/list"

# ==================== 核心爬虫函数 ====================
def crawl(page):
    try:
        # 构造加密参数
        t = int(time.time())
        nonce = ctx.call("nonceStr")
        sign = ctx.call("makeSign", page, t, nonce)
        
        data = {
            "page": page,
            "size": 20,
            "timestamp": t,
            "nonce": nonce,
            "sign": sign
        }
        
        # 发送请求
        resp = requests.post(api, headers=headers, json=data, timeout=15)
        if resp.status_code != 200:
            print(f"第{page}页请求失败")
            return None
        
        res = resp.json()
        if res.get("code") != 0:
            print(f"错误:{res.get('msg')}")
            return None
        
        # 解密密文
        cipher = res.get("data")
        raw_data = ctx.call("decrypt", cipher)
        return json.loads(raw_data)
    
    except Exception as e:
        print(f"异常:{str(e)}")
        return None

# ==================== 批量爬取 + 保存 ====================
def run():
    all_data = []
    # 爬取 5 页
    for page in range(1, 6):
        print(f"正在爬取第 {page} 页")
        page_data = crawl(page)
        if page_data:
            all_data.extend(page_data)
        time.sleep(1)
    
    # 保存 Excel
    df = pd.DataFrame(all_data)
    df.to_excel("爬虫结果.xlsx", index=False)
    print("爬取完成,已保存为 爬虫结果.xlsx")

if __name__ == "__main__":
    run()

6.2 代码说明

  1. 内置完整 JS 加密逻辑,无需外部文件;
  2. 自动生成时间戳、随机串、签名;
  3. 自动解密接口返回密文;
  4. 批量爬取多页并保存为 Excel;
  5. 自带延时,降低反爬风险。

七、常见反爬绕过方案

7.1 IP 被封

  • 增加延时 time.sleep(1~3)
  • 使用代理 IP

python

运行

复制代码
proxies = {
    "http": "http://ip:port",
    "https": "https://ip:port"
}
requests.post(..., proxies=proxies)
  • 登录后复制 Cookie 加入 headers
  • 使用 requests.Session() 维持登录态

7.3 签名频繁失效

  • JS 代码可能更新,重新抓包替换;
  • 检查时间戳是否为秒级 / 毫秒级。

7.4 请求频率限制

  • 单线程慢速爬取
  • 随机延时
  • 避免高并发

八、爬虫规范与法律边界

8.1 合法爬虫原则

  • 遵守 robots.txt 协议;
  • 不爬取隐私数据、金融数据、未公开数据;
  • 不用于商业用途、不恶意攻击服务器;
  • 控制频率,不造成服务器压力。

8.2 禁止行为

  • 破解登录、入侵服务器;
  • 大规模爬取导致网站瘫痪;
  • 贩卖爬取数据、非法牟利;
  • 绕开网站加密与防护措施用于非法目的。

九、学习路线总结(从入门到精通)

  1. 入门:Python 基础 + requests + BeautifulSoup 静态爬取;
  2. 进阶:XPath、JsonPath、接口分析、分页爬取;
  3. 精通:JS 逆向、MD5/AES/RSA 加密、模拟浏览器;
  4. 高阶:异步爬虫、分布式爬虫、APP 爬虫、验证码识别。

爬虫的核心不是代码,而是分析能力:分析网页结构、分析接口参数、分析加密逻辑、分析反爬策略。只要掌握分析思路,任何网站都能实现合规爬取。

十、结语

本文从最基础的静态爬虫,到动态接口分析,再到 JS 逆向加密破解,完整覆盖 Python 爬虫核心技术体系。文中代码均为实战可用版本,只需替换目标地址与解析规则,即可快速适配绝大多数网站。

技术本身无对错,关键在于使用者。希望大家在合法合规的前提下学习爬虫技术,用技术创造价值,而不是带来风险。坚持练习、多做实战项目,你也能从爬虫小白成长为逆向高手

相关推荐
深蓝电商API2 小时前
反爬虫对抗策略在海淘场景的应用
爬虫·海淘·反爬
tang777893 小时前
小红书平台用什么代理IP?数据采集IP封禁解决方法
数据库·爬虫·python·网络协议·ip
亿牛云爬虫专家3 小时前
学术文献爬虫 OOM 崩溃与 403 风暴
爬虫·rust·爬虫代理·403·oom killer·学术文献·403 forbidden
IT 行者10 小时前
Web逆向工程AI工具:JSHook MCP,80+专业工具让Claude变JS逆向大师
开发语言·javascript·ecmascript·逆向
嫂子的姐夫12 小时前
33-补环境介绍
爬虫·js逆向·逆向
ZC跨境爬虫17 小时前
Python异步IO详解:原理、应用场景与实战指南(高并发爬虫首选)
爬虫·python·算法·自动化
嫂子的姐夫17 小时前
35-JS VMP技术介绍
爬虫·js逆向
嫂子的姐夫20 小时前
32-字体反爬
爬虫·逆向
IT 行者20 小时前
Web逆向工程AI工具:WebScout MCP Server,给AI装上眼睛和手
人工智能·逆向·web逆向·mcp