前言大量现代前端采用 Vue/React/Ajax 异步渲染页面源码无真实业务数据requests 静态请求只能拿到空壳 HTMLSelenium 驱动真实浏览器内核渲染页面等待接口异步加载完成后提取 DOM 数据但原生 Selenium 自带爬虫特征极易被站点 JS 检测拦截出现弹窗验证、禁止访问。本章围绕无头配置、浏览器指纹隐藏、webdriver 特征剔除、随机 UA 代理对接、等待策略优化落地无缝衔接前文 UA 池、代理 IP 池、Cookie 池实现动态页面稳定抓取。本文所需依赖官方文档超链接Selenium 官方文档Requests 官方文档ChromeOptions 配置文档一、动态页面抓取原理与 Selenium 反爬检测点1.1 JS 渲染数据加载流程浏览器请求首页 HTML→加载 JS 框架→前端异步 fetch/ajax 请求后端数据接口→数据回填 DOM 标签requests 仅获取第一步原始 HTML拿不到接口返回数据Selenium 完整模拟浏览器执行全流程。1.2 站点 JS 检测爬虫常用特征window.navigator.webdrivertrue原生驱动标记浏览器参数、弹窗、自动化扩展插件特征请求头固定自动化标识、缺少正常浏览器缓存特征。1.3 优化思路关闭自动化标记、剔除 chrome 运行参数特征、无头模式伪装真机环境、轮换 UA 与代理 IP从底层抹除爬虫指纹。二、环境依赖安装bash运行pip install selenium4.21.0 requests2.31.0备注Selenium4.6 版本内置 chromedriver 自动管理无需手动下载驱动。三、基础无痕 反检测 Chrome 配置封装python运行from selenium.webdriver.chrome.options import Options from selenium import webdriver def get_safe_chrome_options(user_agent:strNone, proxy:strNone) - Options: 构造绕过检测的Chrome配置 chrome_opt Options() # 无头运行无浏览器弹窗 chrome_opt.add_argument(--headlessnew) # 禁用GPU chrome_opt.add_argument(--disable-gpu) # 关闭沙盒Linux服务器必备 chrome_opt.add_argument(--no-sandbox) chrome_opt.add_argument(--disable-dev-shm-usage) # 隐藏自动化控制特征 chrome_opt.add_experimental_option(excludeSwitches, [enable-automation]) chrome_opt.add_experimental_option(useAutomationExtension, False) # 自定义UA if user_agent: chrome_opt.add_argument(f--user-agent{user_agent}) # 配置代理IP ip:port if proxy: chrome_opt.add_argument(f--proxy-serverhttp://{proxy}) return chrome_opt def init_safe_driver(uaNone,proxyNone): opt get_safe_chrome_options(ua,proxy) driver webdriver.Chrome(optionsopt) # JS脚本剔除webdriver检测标记 driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}) }) # 设置页面加载超时 driver.set_page_load_timeout(15) driver.implicitly_wait(3) return driver配置原理excludeSwitches关闭自动化启动参数规避浏览器启动特征CDP 注入 JS 覆盖 navigator.webdriver消除最核心爬虫检测字段new 版本无头区别旧版无头浏览器指纹更贴近真机。四、显式等待精准加载策略放弃固定 sleep 浪费资源固定 sleep 等待受网速波动影响过大使用 WebDriverWait 等待目标元素出现再解析python运行from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def wait_element_load(driver, xpath_str, wait_sec10): 等待元素加载完成返回元素对象 wait WebDriverWait(driver, wait_sec) elem wait.until(EC.presence_of_element_located((By.XPATH, xpath_str))) return elem五、单页面动态数据抓取示例python运行def selenium_dynamic_crawl(target_url,rand_uaNone,rand_proxyNone): driver init_safe_driver(uarand_ua,proxyrand_proxy) try: driver.get(target_url) # 等待商品列表DOM渲染完毕 wait_element_load(driver,//div[classgoods-item]) # 批量提取数据 item_elems driver.find_elements(By.XPATH,//div[classgoods-item]) res_list [] for item in item_elems: title item.find_element(By.XPATH,.//div[classtitle]).text price item.find_element(By.XPATH,.//span[classprice]).text res_list.append({title:title,price:price}) return res_list except Exception as e: print(抓取异常,e) return [] finally: driver.quit() # 调用测试 if __name__ __main__: data selenium_dynamic_crawl(https://demo-vue-goods.com/list) print(data)六、对接代理池 UA 池实现动态轮换全反爬组合复用前面代理、UA 接口每次启动浏览器随机参数python运行import requests # 代理、UA接口地址 PROXY_API http://127.0.0.1:5010/get_proxy UA_API http://127.0.0.1:5011/get_ua def get_pool_resource(): 从各自资源池获取UA与代理 # 获取代理 p_res requests.get(PROXY_API).json() proxy p_res[proxy] if p_res[code]200 else None # 模拟UA获取对接UA池接口 ua requests.get(http://127.0.0.1:5010/get_ua).text return ua,proxy def pool_all_crawl(url): ua,proxy get_pool_resource() return selenium_dynamic_crawl(url,rand_uaua,rand_proxyproxy)七、Selenium 携带 Cookie 登录态抓取会员数据复用 Cookie 池字符串启动浏览器后写入 Cookie 实现免登录访问python运行def driver_add_cookie(driver,cookie_str,domain): cookie字符串转为字典批量写入浏览器 ck_items cookie_str.split(; ) for ck in ck_items: k,v ck.split(,1) cookie_dict {name:k,value:v,domain:domain} driver.add_cookie(cookie_dict) def crawl_with_login_cookie(target_url,cookie_str,domain): driver init_safe_driver() # 先访问域名再写入cookie driver.get(domain) driver_add_cookie(driver,cookie_str,domain) driver.get(target_url) # 等待数据渲染 wait_element_load(driver,//div[contains(class,vip-data)]) # 解析会员数据 info driver.find_element(By.XPATH,//div[classvip-info]).text driver.quit() return info八、分页滚动懒加载页面处理商品列表滚动到底部才加载下一页数据模拟鼠标下滑触发异步请求python运行import time def scroll_load_all_data(driver): last_height driver.execute_script(return document.body.scrollHeight) while True: # 滚动到页面底部 driver.execute_script(window.scrollTo(0,document.body.scrollHeight)) time.sleep(1.2) new_height driver.execute_script(return document.body.scrollHeight) if new_height last_height: break last_height new_height # 滚动完毕后统一提取全部数据 all_items driver.find_elements(By.CLASS_NAME,goods-item) return [i.text for i in all_items]九、Linux 服务器无桌面部署优化服务器无图形界面必开配置python运行chrome_opt.add_argument(--disable-gpu) chrome_opt.add_argument(--headlessnew) chrome_opt.add_argument(--no-sandbox) chrome_opt.add_argument(--disable-dev-shm-usage)部署方式搭配 nohup 后台常驻爬虫脚本。十、常见报错与优化方案表格异常解决方案webdriver 特征被拦截CDP 注入 JS 抹除 navigator.webdriver 字段使用新版无头页面加载超时缩短 page_load_timeout拆分分页抓取浏览器进程残留占用内存finally 强制 driver.quit ()定时杀残留 chrome 进程频繁被封 IP每次实例新浏览器搭配不同代理 IPUA
Python 爬虫 Selenium 无头浏览器实战:JS 动态渲染数据全量抓取 + 反检测绕过
发布时间:2026/6/4 20:35:04
前言大量现代前端采用 Vue/React/Ajax 异步渲染页面源码无真实业务数据requests 静态请求只能拿到空壳 HTMLSelenium 驱动真实浏览器内核渲染页面等待接口异步加载完成后提取 DOM 数据但原生 Selenium 自带爬虫特征极易被站点 JS 检测拦截出现弹窗验证、禁止访问。本章围绕无头配置、浏览器指纹隐藏、webdriver 特征剔除、随机 UA 代理对接、等待策略优化落地无缝衔接前文 UA 池、代理 IP 池、Cookie 池实现动态页面稳定抓取。本文所需依赖官方文档超链接Selenium 官方文档Requests 官方文档ChromeOptions 配置文档一、动态页面抓取原理与 Selenium 反爬检测点1.1 JS 渲染数据加载流程浏览器请求首页 HTML→加载 JS 框架→前端异步 fetch/ajax 请求后端数据接口→数据回填 DOM 标签requests 仅获取第一步原始 HTML拿不到接口返回数据Selenium 完整模拟浏览器执行全流程。1.2 站点 JS 检测爬虫常用特征window.navigator.webdrivertrue原生驱动标记浏览器参数、弹窗、自动化扩展插件特征请求头固定自动化标识、缺少正常浏览器缓存特征。1.3 优化思路关闭自动化标记、剔除 chrome 运行参数特征、无头模式伪装真机环境、轮换 UA 与代理 IP从底层抹除爬虫指纹。二、环境依赖安装bash运行pip install selenium4.21.0 requests2.31.0备注Selenium4.6 版本内置 chromedriver 自动管理无需手动下载驱动。三、基础无痕 反检测 Chrome 配置封装python运行from selenium.webdriver.chrome.options import Options from selenium import webdriver def get_safe_chrome_options(user_agent:strNone, proxy:strNone) - Options: 构造绕过检测的Chrome配置 chrome_opt Options() # 无头运行无浏览器弹窗 chrome_opt.add_argument(--headlessnew) # 禁用GPU chrome_opt.add_argument(--disable-gpu) # 关闭沙盒Linux服务器必备 chrome_opt.add_argument(--no-sandbox) chrome_opt.add_argument(--disable-dev-shm-usage) # 隐藏自动化控制特征 chrome_opt.add_experimental_option(excludeSwitches, [enable-automation]) chrome_opt.add_experimental_option(useAutomationExtension, False) # 自定义UA if user_agent: chrome_opt.add_argument(f--user-agent{user_agent}) # 配置代理IP ip:port if proxy: chrome_opt.add_argument(f--proxy-serverhttp://{proxy}) return chrome_opt def init_safe_driver(uaNone,proxyNone): opt get_safe_chrome_options(ua,proxy) driver webdriver.Chrome(optionsopt) # JS脚本剔除webdriver检测标记 driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, {get: () undefined}) }) # 设置页面加载超时 driver.set_page_load_timeout(15) driver.implicitly_wait(3) return driver配置原理excludeSwitches关闭自动化启动参数规避浏览器启动特征CDP 注入 JS 覆盖 navigator.webdriver消除最核心爬虫检测字段new 版本无头区别旧版无头浏览器指纹更贴近真机。四、显式等待精准加载策略放弃固定 sleep 浪费资源固定 sleep 等待受网速波动影响过大使用 WebDriverWait 等待目标元素出现再解析python运行from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def wait_element_load(driver, xpath_str, wait_sec10): 等待元素加载完成返回元素对象 wait WebDriverWait(driver, wait_sec) elem wait.until(EC.presence_of_element_located((By.XPATH, xpath_str))) return elem五、单页面动态数据抓取示例python运行def selenium_dynamic_crawl(target_url,rand_uaNone,rand_proxyNone): driver init_safe_driver(uarand_ua,proxyrand_proxy) try: driver.get(target_url) # 等待商品列表DOM渲染完毕 wait_element_load(driver,//div[classgoods-item]) # 批量提取数据 item_elems driver.find_elements(By.XPATH,//div[classgoods-item]) res_list [] for item in item_elems: title item.find_element(By.XPATH,.//div[classtitle]).text price item.find_element(By.XPATH,.//span[classprice]).text res_list.append({title:title,price:price}) return res_list except Exception as e: print(抓取异常,e) return [] finally: driver.quit() # 调用测试 if __name__ __main__: data selenium_dynamic_crawl(https://demo-vue-goods.com/list) print(data)六、对接代理池 UA 池实现动态轮换全反爬组合复用前面代理、UA 接口每次启动浏览器随机参数python运行import requests # 代理、UA接口地址 PROXY_API http://127.0.0.1:5010/get_proxy UA_API http://127.0.0.1:5011/get_ua def get_pool_resource(): 从各自资源池获取UA与代理 # 获取代理 p_res requests.get(PROXY_API).json() proxy p_res[proxy] if p_res[code]200 else None # 模拟UA获取对接UA池接口 ua requests.get(http://127.0.0.1:5010/get_ua).text return ua,proxy def pool_all_crawl(url): ua,proxy get_pool_resource() return selenium_dynamic_crawl(url,rand_uaua,rand_proxyproxy)七、Selenium 携带 Cookie 登录态抓取会员数据复用 Cookie 池字符串启动浏览器后写入 Cookie 实现免登录访问python运行def driver_add_cookie(driver,cookie_str,domain): cookie字符串转为字典批量写入浏览器 ck_items cookie_str.split(; ) for ck in ck_items: k,v ck.split(,1) cookie_dict {name:k,value:v,domain:domain} driver.add_cookie(cookie_dict) def crawl_with_login_cookie(target_url,cookie_str,domain): driver init_safe_driver() # 先访问域名再写入cookie driver.get(domain) driver_add_cookie(driver,cookie_str,domain) driver.get(target_url) # 等待数据渲染 wait_element_load(driver,//div[contains(class,vip-data)]) # 解析会员数据 info driver.find_element(By.XPATH,//div[classvip-info]).text driver.quit() return info八、分页滚动懒加载页面处理商品列表滚动到底部才加载下一页数据模拟鼠标下滑触发异步请求python运行import time def scroll_load_all_data(driver): last_height driver.execute_script(return document.body.scrollHeight) while True: # 滚动到页面底部 driver.execute_script(window.scrollTo(0,document.body.scrollHeight)) time.sleep(1.2) new_height driver.execute_script(return document.body.scrollHeight) if new_height last_height: break last_height new_height # 滚动完毕后统一提取全部数据 all_items driver.find_elements(By.CLASS_NAME,goods-item) return [i.text for i in all_items]九、Linux 服务器无桌面部署优化服务器无图形界面必开配置python运行chrome_opt.add_argument(--disable-gpu) chrome_opt.add_argument(--headlessnew) chrome_opt.add_argument(--no-sandbox) chrome_opt.add_argument(--disable-dev-shm-usage)部署方式搭配 nohup 后台常驻爬虫脚本。十、常见报错与优化方案表格异常解决方案webdriver 特征被拦截CDP 注入 JS 抹除 navigator.webdriver 字段使用新版无头页面加载超时缩短 page_load_timeout拆分分页抓取浏览器进程残留占用内存finally 强制 driver.quit ()定时杀残留 chrome 进程频繁被封 IP每次实例新浏览器搭配不同代理 IPUA