【爬虫学习】动态网页数据抓取实战:Ajax逆向与浏览器自动化
【爬虫学习】动态网页数据抓取实战:Ajax逆向与浏览器自动化
摘要
针对现代网站的动态化趋势,本文深入解析Ajax接口逆向与浏览器自动化技术。通过微博热搜实时数据抓取、知乎无限滚动内容采集等实战案例,演示如何突破动态渲染壁垒,实现结构化数据提取。
一、Ajax接口逆向实战:微博热搜数据采集
动态网页的核心特征是通过JavaScript异步加载数据,需绕过前端渲染直接获取原始API数据。
1.1 接口捕获全流程解析
工具链:Chrome开发者工具 + Postman
- 开启抓包:F12打开开发者工具,切换至Network面板,勾选
Preserve log
- 触发数据加载:刷新页面或滚动触发XHR请求
- 筛选请求:通过
XHR/fetch
类型过滤,定位包含关键词(如hot
、feed
)的请求 - 分析请求:
- Headers:重点关注
Referer
、User-Agent
、X-Requested-With
- Params:识别分页参数(如
max_id
)、加密参数(如签名) - Response:验证数据结构是否包含目标内容
- Headers:重点关注
典型微博热搜接口:
https://weibo.com/ajax/statuses/hot_band?containerid=106003type%3D25%26t%3D3%26disable_hot%3D1%26filter_type%3Drealtimehot
1.2 参数加密逆向分析
常见加密手段:
- 时间戳签名:如
_rnd
参数为当前时间戳,用于防止重放攻击params["_rnd"] = str(int(time.time() * 1000))
- Cookie依赖:部分接口需验证
SUB
Cookie(用户身份标识)headers["Cookie"] = "SUB=_2A25JsExample; SUBP=Example;"
- 动态签名:复杂场景需逆向JS生成签名(如
gsid
参数)- 使用
js2py
或PyExecJS
执行浏览器环境JS代码
- 使用
1.3 完整采集代码实现
import requests
import time
import json
class WeiboHotScraper:
def __init__(self):
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
"Referer": "https://weibo.com/hot"
}
self.api_url = "https://weibo.com/ajax/statuses/hot_band"
self.max_id = 0 # 分页标识
def get_hot_list(self):
params = {
"containerid": "106003type%3D25%26t%3D3%26disable_hot%3D1%26filter_type%3Drealtimehot",
"max_id": self.max_id,
"_rnd": int(time.time() * 1000)
}
response = requests.get(self.api_url, headers=self.headers, params=params)
if response.status_code != 200:
raise RequestError("API request failed")
data = response.json()
if not data.get("data"):
return None
hot_items = data["data"]["band_list"]
self.max_id = data["data"]["max_id"] # 更新下一页标识
return hot_items
def run(self):
all_hot = []
while True:
items = self.get_hot_list()
if not items:
break
all_hot.extend(items)
time.sleep(2) # 模拟人类操作间隔
return all_hot
# 使用示例
scraper = WeiboHotScraper()
hot_data = scraper.run()
json.dump(hot_data, open("weibo_hot.json", "w", encoding="utf-8"), ensure_ascii=False)
二、浏览器自动化进阶:知乎无限滚动内容抓取
对于依赖JavaScript动态渲染的页面(如无限滚动加载),需借助浏览器自动化工具模拟用户行为。
2.1 Selenium反检测技术
现代网站通过navigator.webdriver
等属性检测自动化程序,可通过以下手段规避:
- 修改浏览器指纹:
options = webdriver.ChromeOptions() options.add_argument("--disable-blink-features=AutomationControlled") options.add_argument(f"user-agent={generate_random_user_agent()}")
- 注入自定义JS:
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ delete window.cdc_adoQpoasnfa76pfcZLmcfl_; Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); """ })
2.2 动态加载内容捕获
无限滚动处理三步骤:
- 定位加载容器:通过
driver.find_element(By.CSS_SELECTOR, ".List")
确定内容区域 - 模拟滚动行为:
def scroll_to_bottom(driver, scroll_pause=2): last_height = driver.execute_script("return document.body.scrollHeight") while True: driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(scroll_pause) new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break # 到达底部 last_height = new_height
- 显式等待优化:
from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) wait.until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "ContentItem")))
2.3 知乎回答采集完整流程
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
class ZhihuScraper:
def __init__(self):
self.options = webdriver.ChromeOptions()
self.options.add_argument("--headless=new") # 无界面模式
self.options.add_argument("--disable-gpu")
self.driver = webdriver.Chrome(options=self.options)
def open_question(self, question_id):
url = f"https://www.zhihu.com/question/{question_id}"
self.driver.get(url)
time.sleep(3) # 等待初始加载
def scroll_and_collect(self):
scroll_to_bottom(self.driver) # 执行滚动加载
answers = self.driver.find_elements(By.CSS_SELECTOR, ".QuestionAnswer-content")
return [answer.text for answer in answers]
def close(self):
self.driver.quit()
# 使用示例
scraper = ZhihuScraper()
scraper.open_question("456789")
answers = scraper.scroll_and_collect()
scraper.close()
三、动态反爬应对策略与性能优化
3.1 反爬应对矩阵
反爬手段 | 应对方案 |
---|---|
IP封禁 | 代理池+IP轮换策略 |
User-Agent检测 | 随机UA生成+浏览器指纹模拟 |
验证码 | 第三方打码平台(如极验、12306) |
请求频率限制 | 随机延迟+请求间隔抖动 |
JS动态加密 | 逆向分析+模拟加密逻辑 |
3.2 性能优化技巧
- 无头模式:
options.add_argument("--headless=new")
减少资源占用 - 隐式等待替代:避免
time.sleep()
固定延迟,使用WebDriverWait
智能等待 - 批量元素定位:通过
find_elements
一次性获取所有元素,减少DOM查询次数 - 懒加载处理:对未可见元素使用
driver.execute_script("arguments[0].scrollIntoView();", element)
触发加载
总结
动态网页采集需综合运用接口逆向、浏览器自动化、反检测等技术。实际项目中应优先分析是否存在未加密的API接口,避免直接与前端对抗。对于必须使用浏览器自动化的场景,需平衡采集效率与反爬风险,通过代理池、请求间隔控制等手段构建可持续的采集方案。
本文地址:https://www.vps345.com/12718.html