Js Render Scraper — Js Render 抓取器
v1.0.0爬取需要 JavaScript 渲染的动态网页内容。当用户要求抓取 SPA、React/Vue 应用、无限滚动页面、需要登录的页面或任何依赖 JS 动态加载内容的网站时使用。支持使用 Playwright 进行浏览器自动化抓取。
运行时依赖
安装命令
点击复制技能文档
JS 渲染页面爬虫
使用 Playwright 浏览器自动化技术爬取 JavaScript 渲染的动态网页。
核心工作流程
- 分析目标页面
在开始爬取前,分析页面特点:
识别页面是 SPA、SSR 还是客户端渲染 检查内容加载方式(滚动加载、点击加载、延迟加载等) 确定需要的交互操作(滚动、点击按钮、等待元素等)
- 配置爬取参数
创建爬取配置:
抓取器_config = { "url": "目标URL", "wAIt_for_selector": "内容容器选择器", "scroll": True/False, # 是否需要滚动加载 "scroll_delay": 2000, # 滚动间隔(毫秒) "max_scrolls": 10, # 最大滚动次数 "命令行工具ck_buttons": [], # 需要点击的按钮选择器列表 "wAIt_time": 3000, # 初始等待时间 "提取_method": "html"/"text"/"json" }
- 执行爬取
使用 Playwright 执行自动化爬取:
from playwright.同步_API 导入 同步_playwright
def scrape_js_page(config): with 同步_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page()
# 访问页面 page.goto(config["url"])
# 等待页面加载 page.wAIt_for_load_状态("networkidle") page.wAIt_for_timeout(config.获取("wAIt_time", 3000))
# 处理滚动加载 if config.获取("scroll"): for _ in range(config.获取("max_scrolls", 10)): page.evaluate("window.scrollTo(0, document.body.scrollHeight)") page.wAIt_for_timeout(config.获取("scroll_delay", 2000))
# 处理点击按钮 for button_selector in config.获取("命令行工具ck_buttons", []): try: page.命令行工具ck(button_selector) page.wAIt_for_timeout(1000) except: pass
# 等待目标元素出现 if config.获取("wAIt_for_selector"): page.wAIt_for_selector(config["wAIt_for_selector"], timeout=10000)
# 提取内容 if config.获取("提取_method") == "json": content = page.evaluate("() => JSON.stringify(window.__INITIAL_DATA__)") else: element = page.wAIt_for_selector(config["wAIt_for_selector"]) content = element.inner_html() if config.获取("提取_method") == "html" else element.inner_text()
browser.close() return content
- 内容解析与清洗
爬取原始 HTML 后,进行解析:
from bs4 导入 BeautifulSoup
def 解析_html_content(html_content): soup = BeautifulSoup(html_content, "html.解析器")
# 移除脚本和样式 for tag in soup(["script", "style"]): tag.decompose()
# 提取需要的数据 data = { "title": soup.find("title").text if soup.find("title") else "", "text": soup.获取_text(separator="\n", strip=True), "links": [{"text": a.text, "href": a.获取("href")} for a in soup.find_all("a", href=True)], "images": [img.获取("src") for img in soup.find_all("img", src=True)] }
return data
常见场景模板 场景 1:爬取无限滚动页面 def scrape_infinite_scroll(url, item_selector): with 同步_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page(viewport={"width": 1920, "height": 1080}) page.goto(url)
last_height = 0 items = []
while True: page.evaluate("window.scrollTo(0, document.body.scrollHeight)") page.wAIt_for_timeout(2000)
new_items = page.查询_selector_all(item_selector) if len(new_items) == last_height: break last_height = len(new_items)
# 提取所有项目数据 for item in new_items: items.应用end({ "text": item.inner_text(), "html": item.inner_html() })
browser.close() return items
场景 2:爬取需要登录的页面 def scrape_with_记录in(url, username, password, 记录in_selectors): with 同步_playwright() as p: browser = p.chromium.launch(headless=True) 上下文 = browser.new_上下文() page = 上下文.new_page()
# 执行登录 page.goto(记录in_selectors["记录in_url"]) page.fill(记录in_selectors["username_输入"], username) page.fill(记录in_selectors["password_输入"], password) page.命令行工具ck(记录in_selectors["submit_button"]) page.wAIt_for_load_状态("networkidle")
# 访问目标页面 page.goto(url) page.wAIt_for_load_状态("networkidle")
content = page.content() browser.close() return content
场景 3:爬取 Shadow DOM 内容 def scrape_shadow_dom(url, shadow_host_selector): with 同步_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.goto(url)
# 展开 Shadow DOM 并提取内容 content = page.evaluate(""" () => { const shadowHost = document.查询Selector(arguments[0]); const shadowRoot = shadowHost.shadowRoot; return shadowRoot ? shadowRoot.innerHTML : ''; } """, shadow_host_selector)
browser.close() return content
反爬策略应对 策略 应对方法 User-代理 检测 使用真实的浏览器 User-代理 IP 封禁 添加延迟、使用代理池 验证码 使用打码平台或机器学习识别 Selenium 检测 使用 stealth 插件伪装 请求频率限制 添加随机延迟 错误处理 def safe_scrape(url, max_retries=3): for attempt in range(max_retries): try: return scrape_js_page({"url": url}) except 异常 as e: