欢迎光临
我们一直在努力

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

前言

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

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

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

一、爬虫前置基础认知

1.1 什么是网络爬虫

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

1.2 爬虫能做什么

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

1.3 爬虫分类

  • 静态爬虫:爬取纯 HTML 页面,数据直接写在网页源码中,无加密、无异步加载;
  • 动态爬虫:针对 Ajax、Fetch 异步加载接口,需要分析接口参数;
  • 逆向爬虫:破解前端 JS 加密、参数签名、数据加密等反爬逻辑;
  • 模拟浏览器爬虫:使用 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 静态爬虫核心流程

  • 构造请求头,模拟浏览器访问;
  • 发送 GET 请求,获取网页源码;
  • 使用 BeautifulSoup 解析 HTML;
  • 提取标题、链接、时间等目标数据;
  • 数据清洗与简单存储。
  • 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 抓包步骤

  • 打开目标网站 → F12 → Network;
  • 勾选 Preserve log、筛选 XHR/Fetch;
  • 刷新页面或翻页,查看出现的接口;
  • 查看接口 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 代码

  • 在 Network 面板 Ctrl+F 搜索 sign、encrypt、md5、aes;
  • 在 Source 面板查找混淆 / 压缩的 JS 文件;
  • 使用断点调试,查看参数生成过程。
  • 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 代码说明

  • 内置完整 JS 加密逻辑,无需外部文件;
  • 自动生成时间戳、随机串、签名;
  • 自动解密接口返回密文;
  • 批量爬取多页并保存为 Excel;
  • 自带延时,降低反爬风险。
  • 七、常见反爬绕过方案

    7.1 IP 被封

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

    python

    运行

    proxies = {
    "http": "http://ip:port",
    "https": "https://ip:port"
    }
    requests.post(…, proxies=proxies)

    7.2 Cookie 验证

    • 登录后复制 Cookie 加入 headers
    • 使用 requests.Session() 维持登录态

    7.3 签名频繁失效

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

    7.4 请求频率限制

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

    八、爬虫规范与法律边界

    8.1 合法爬虫原则

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

    8.2 禁止行为

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

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

  • 入门:Python 基础 + requests + BeautifulSoup 静态爬取;
  • 进阶:XPath、JsonPath、接口分析、分页爬取;
  • 精通:JS 逆向、MD5/AES/RSA 加密、模拟浏览器;
  • 高阶:异步爬虫、分布式爬虫、APP 爬虫、验证码识别。
  • 爬虫的核心不是代码,而是分析能力:分析网页结构、分析接口参数、分析加密逻辑、分析反爬策略。只要掌握分析思路,任何网站都能实现合规爬取。

    十、结语

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

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

    赞(0)
    未经允许不得转载:171主机测评 » Python 爬虫实战:从入门到精通,爬取某站数据
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址