M2LOrder模型Python爬虫实战:应对动态渲染与数据加密网站
M2LOrder模型Python爬虫实战应对动态渲染与数据加密网站最近有个朋友找我帮忙说他们公司需要从某个网站上抓取一些商品数据但试了好几个爬虫工具都搞不定。我一看好家伙这网站不仅数据是页面加载完才动态生成的关键请求里还带了一串看不懂的加密参数。这不就是典型的“动态渲染数据加密”双重防御嘛。这种网站对传统爬虫来说简直是噩梦。用requests直接请求拿到的HTML里空空如也关键数据影子都见不着。用Selenium或Playwright这类浏览器自动化工具吧虽然能看到数据了但那些带加密参数的接口请求你照样模拟不了数据还是拿不到完整的。正好我之前研究过M2LOrder模型在解决这类复杂问题上的思路它那种“观察-分析-模拟-逆向”的链条特别适合对付这种硬骨头。所以我就用这个棘手的案例给大家展示一下怎么一步步把这块难啃的骨头给啃下来。整个过程就像一次技术侦探破案。1. 目标网站分析与难点定位在动手写任何代码之前搞清楚“敌情”是第一步。我们这次要对付的网站这里我们用一个符合规范的示例网站example-mall.com来代指表面上看是个普通的电商列表页。1.1 第一层难点动态渲染如果你用最简单的requests库去请求它的商品列表页代码大概长这样import requests url ‘https://example-mall.com/products‘ response requests.get(url) print(response.text[:1000]) # 只打印前1000字符看看你会发现打印出来的HTML里商品列表的区域往往是类似这样的结构div id“product-list” !-- 商品数据将由JavaScript动态加载 -- /div真正的商品信息比如图片、价格、名称在初始的HTML响应里根本不存在。它们是在页面加载完成后由浏览器执行JavaScript代码再向后台某个接口发起请求获取数据最后动态插入到这个div里的。这就是动态渲染。你直接抓取静态HTML等于扑了个空。1.2 第二层难点请求加密既然数据来自另一个接口那我们去找到这个接口不就行了用浏览器的开发者工具按F12切换到Network网络标签页刷新页面仔细查看所有的XHR或Fetch请求。很快你会发现一个类似https://api.example-mall.com/getProducts?page1txyzsignabc123...的请求。这个请求返回了清晰的JSON数据正是我们想要的。但问题来了这个请求的URL里有两个可疑参数t和sign。t看起来像时间戳但可能经过了处理sign就更明显了通常是“签名”参数用于防止请求被伪造。如果你直接复制这个URL用requests去请求很可能会返回“签名错误”或“请求无效”。这就是请求加密更准确说是参数签名。服务器要求客户端在发起请求时必须按照它规定的算法生成一个正确的sign值否则就拒绝服务。这个生成sign的算法通常隐藏在网站加载的某个JavaScript文件里。所以我们的核心任务从“下载页面”变成了让浏览器环境执行JS渲染出页面。在浏览器环境中拦截或分析出那个获取数据的真实接口。逆向分析出接口参数尤其是sign的生成算法。用Python模拟这个算法构造出合法的请求直接获取数据。2. 工具选择与M2LOrder思路应用面对这个复合型难题单一工具很难完美解决。这里就需要用到M2LOrder模型倡导的“分层处理、工具链协同”的思路。2.1 分层策略我们可以把问题分解为两个层面渲染层解决“看到数据”的问题。我们需要一个能执行JavaScript的浏览器环境。数据层解决“拿到数据”的问题。我们需要能分析网络请求并模拟其逻辑。2.2 工具链搭配根据M2LOrder的实践一个高效的组合是Playwright主攻渲染层比Selenium更现代启动更快API更优雅。它不仅能无头运行浏览器其强大的“请求/响应”拦截和监听功能是我们破解数据接口的关键。浏览器开发者工具辅助分析手动分析请求、搜索加密关键字、调试JS代码离不开它。Python 相关库主攻数据层包括requests用于最终的数据抓取hashlib,hmac,json等用于可能涉及的加密算法模拟以及re,execjs等用于解析和执行JS代码片段。M2LOrder的核心思路在这里体现为不用Playwright去笨拙地抓取每一个渲染后的DOM元素慢且不稳定而是用它作为“侦察兵”帮我们找出获取数据的“秘密通道”API和“通关密码”加密算法。一旦密码破译我们就让高效的requests通过这条通道直接搬运数据。3. 实战破解从渲染到逆向下面我们开始真正的“破案”流程。3.1 第一步使用Playwright监听网络请求我们首先写一个脚本用Playwright打开目标页面并监听所有网络响应特别是JSON格式的响应从中找到那个携带商品数据的接口。import asyncio from playwright.async_api import async_playwright async def find_data_api(): async with async_playwright() as p: # 启动浏览器推荐用Chromium无头模式更快 browser await p.chromium.launch(headlessTrue) context await browser.new_context() page await context.new_page() # 准备一个列表来收集可能的数据接口 data_api_candidates [] # 监听所有响应事件 def on_response(response): url response.url # 筛选出可能是数据API的请求 if ‘api‘ in url and ‘getProducts‘ in url: print(f‘发现疑似数据接口: {url}‘) print(f‘ 状态码: {response.status}‘) # 尝试获取响应体如果是JSON则打印一部分看看 try: # 注意这里为了演示我们直接await在实际监听函数中需要小心处理异步 # 更稳妥的做法是记录下URL后续再集中处理 data_api_candidates.append(url) except: pass page.on(‘response‘, on_response) # 导航到目标页面 await page.goto(‘https://example-mall.com/products‘) # 等待页面可能触发的动态加载完成可以根据实际情况调整等待条件或时间 await page.wait_for_timeout(3000) # 等待3秒 # 这里为了简化我们直接打印候选接口。实际项目中可能需要更复杂的判断。 print(‘\n候选接口列表:‘) for api in data_api_candidates[:5]: # 只打印前5个 print(f‘ - {api}‘) await browser.close() # 运行 asyncio.run(find_data_api())运行这个脚本你大概率会在控制台看到那个关键的API地址比如https://api.example-mall.com/v1/products/list?page1t1648886400123sign7a89f8d7e...。3.2 第二步逆向加密参数找到接口后最硬核的部分来了——破解sign的生成算法。定位加密代码在开发者工具的Network标签页找到这个接口的请求点击它查看Headers和Initiator标签。Initiator会显示是哪个JS文件发起了这个请求。点击跳转到该JS文件Sources标签。搜索关键字段在JS文件里使用CtrlF搜索关键词如sign,encrypt,md5,hmac,SHA或者参数名t。你可能会找到一段混淆过的代码但核心逻辑通常围绕几个变量展开。分析逻辑找到的代码可能长这样已简化function generateSign(params) { var key ‘a_secret_key‘; var str Object.keys(params).sort().map(k k ‘‘ params[k]).join(‘‘); str str ‘key‘ key; // 假设这里是MD5也可能是其他哈希或自定义算法 return md5(str).toUpperCase(); } var t Date.now(); var params {‘page‘: 1, ‘t‘: t}; params[‘sign‘] generateSign(params);核心是将请求参数包括一个时间戳t和一个密钥key按特定格式拼接成一个字符串然后对这个字符串进行哈希运算如MD5、SHA1得到sign。Python模拟算法一旦弄清了算法用Python实现它就很简单了。import hashlib import time import urllib.parse def generate_sign(page): # 1. 准备参数。密钥‘a_secret_key‘是通过逆向JS发现的。 secret_key ‘a_secret_key‘ # t 通常是当前时间戳有时是13位毫秒级 t int(time.time() * 1000) params { ‘page‘: page, ‘t‘: t } # 2. 按“键值”的格式排序并拼接与JS逻辑一致 sorted_params sorted(params.items(), keylambda x: x[0]) param_str ‘‘.join([f‘{k}{v}‘ for k, v in sorted_params]) # 3. 拼接密钥 sign_str param_str ‘key‘ secret_key # 4. 计算MD5并转为大写 m hashlib.md5() m.update(sign_str.encode(‘utf-8‘)) return t, m.hexdigest().upper() # 测试生成第一页的签名 timestamp, sign generate_sign(1) print(f‘生成的 t: {timestamp}‘) print(f‘生成的 sign: {sign}‘)3.3 第三步组装并请求数据现在我们有了合法的t和sign就可以用requests像正常客户端一样请求数据了。import requests def fetch_products_by_page(page_num): base_url ‘https://api.example-mall.com/v1/products/list‘ t, sign generate_sign(page_num) params { ‘page‘: page_num, ‘t‘: t, ‘sign‘: sign } headers { ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...‘ } try: response requests.get(base_url, paramsparams, headersheaders, timeout10) response.raise_for_status() # 检查请求是否成功 data response.json() return data except requests.exceptions.RequestException as e: print(f‘请求第{page_num}页失败: {e}‘) return None # 抓取第一页数据 page1_data fetch_products_by_page(1) if page1_data and page1_data.get(‘code‘) 0: # 假设成功码是0 products page1_data.get(‘data‘, {}).get(‘list‘, []) print(f‘成功抓取到 {len(products)} 条商品数据‘) for product in products[:2]: # 打印前两个商品看看 print(f‘ 商品名: {product.get(“name“)} 价格: {product.get(“price“)}‘) else: print(‘数据抓取失败‘, page1_data)4. 效果展示与完整流程回顾让我们来看看这套组合拳打出来的效果。传统爬虫方式如纯Requests面对目标网站直接返回空列表或包含JS代码的HTML无法获取核心商品数据。纯浏览器自动化方式如仅用Playwright抓DOM可以获取到渲染后的商品名、价格但需要通过page.locator(‘.product-item‘).all()等方式解析DOM速度慢且代码受网页布局变动影响大。对于分页等操作也需要模拟点击效率不高。应用M2LOrder思路后的方式侦察阶段利用Playwright的浏览器环境轻松捕获到动态加载的真实数据接口https://api.example-mall.com/v1/products/list。分析阶段通过开发者工具逆向出该接口用于验证的sign参数生成算法MD5哈希。模拟阶段用Python的hashlib库完美复现该算法。收割阶段使用高效的requests库携带自生成的合法参数直接请求接口获得结构化的JSON数据。速度极快且不受前端页面样式变化的影响。最终成果我们获得了一个稳定、高效的数据管道。只需运行fetch_products_by_page函数传入页码就能秒级获取该页所有商品的标准化数据JSON格式远比从HTML中解析要可靠和快速。5. 总结这次实战与其说是在讲一个爬虫教程不如说是在展示一种解决复杂技术问题的思路。M2LOrder模型在这里给我们的启示是不要硬碰硬。当网站用动态渲染和数据加密筑起高墙时我们不必非要造个更高的梯子更复杂的渲染解析而是可以想办法找到它的后门分析API并配一把钥匙逆向加密算法。整个过程的关键在于耐心和细致的观察分析。Playwright是我们深入敌后的“眼睛”而浏览器开发者工具是我们破解密码的“放大镜”。一旦找到了规律用Python实现模拟就是水到渠成的事情。这种“渲染环境侦察 核心逻辑逆向 高效请求模拟”的分层策略对于应对现代Web开发中日益复杂的反爬机制是一个非常有效且值得掌握的套路。下次你再遇到类似的难题不妨也试试沿着这个思路走一遍。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2472142.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!