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 --version2.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/simple2.3 Node.js 环境安装
JS 逆向需要执行前端加密代码,依赖 Node.js 环境。下载地址:https://nodejs.org/ 安装 LTS 版本。
验证安装:
bash
运行
node -v npm -v安装 crypto-js 用于加密算法:
bash
运行
npm install crypto-js2.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 爬虫核心技术体系。文中代码均为实战可用版本,只需替换目标地址与解析规则,即可快速适配绝大多数网站。
技术本身无对错,关键在于使用者。希望大家在合法合规的前提下学习爬虫技术,用技术创造价值,而不是带来风险。坚持练习、多做实战项目,你也能从爬虫小白成长为逆向高手
