// Strategic navigation patterns and selector guides for thorough web exploration using Playwright MCP. Provides decision trees, navigation strategies, and site-specific selectors for reading multiple pages systematically. Use when planning how to navigate websites, determining reading depth, or finding the right selectors for Playwright MCP commands.
| name | web-navigation-strategies |
| description | Strategic navigation patterns and selector guides for thorough web exploration using Playwright MCP. Provides decision trees, navigation strategies, and site-specific selectors for reading multiple pages systematically. Use when planning how to navigate websites, determining reading depth, or finding the right selectors for Playwright MCP commands. |
Strategic guide for systematic web exploration using Playwright MCP tools. This skill provides navigation patterns, not executable code.
Query Analysis Decision Tree:
โโโ Keywords: "๊ฐ๋จํ, ์์ฝ, ํ์ด, quick, summary, overview"
โ โ **QUICK MODE**
โ โ Extract: Titles + First paragraphs only
โ โ Pages: 30-50 (fast scan)
โ
โโโ Keywords: "์์ธํ, ์์ธ, ๋ชจ๋ , ๋๊ธ, detailed, comprehensive, everything"
โ โ **DEEP MODE**
โ โ Extract: Full content + Comments + Metadata + Related links
โ โ Pages: 5-10 (thorough read)
โ
โโโ No specific keywords
โ **STANDARD MODE**
โ Extract: Main content + Basic metadata
โ Pages: 15-20 (balanced)
// Get titles and summaries only
mcp_playwright.navigate(url)
links = mcp_playwright.query_selector_all('h2 a, h3 a')
for (link in links.slice(0, 50)) {
mcp_playwright.click(link)
title = mcp_playwright.get_text('h1')
summary = mcp_playwright.get_text('p:first-of-type')
mcp_playwright.go_back()
}
// Get full main content
mcp_playwright.navigate(url)
links = mcp_playwright.query_selector_all('article a')
for (link in links.slice(0, 20)) {
mcp_playwright.click(link)
mcp_playwright.wait_for_load_state('networkidle')
content = mcp_playwright.get_text('main, article, .content')
mcp_playwright.go_back()
}
// Get everything including discussions
mcp_playwright.navigate(url)
links = mcp_playwright.query_selector_all('article a')
for (link in links.slice(0, 10)) {
mcp_playwright.click(link)
mcp_playwright.wait_for_load_state('networkidle')
// Main content
content = mcp_playwright.get_text('article, main')
// Comments
comments = mcp_playwright.query_selector_all('.comment')
for (comment in comments) {
comment_text = mcp_playwright.get_text(comment)
}
// Metadata
author = mcp_playwright.get_text('.author, .writer')
date = mcp_playwright.get_text('time, .date')
// Related links
related = mcp_playwright.query_selector_all('.related a')
mcp_playwright.go_back()
}
Use for: Blog indexes, search results, news listings
Step-by-Step Process:
1. Navigate to list page
2. Collect all article links
3. For each link:
a. Click link
b. Wait for page load
c. Extract content
d. Navigate back
e. Continue with next
MCP Commands:
// Navigate to list
mcp_playwright.navigate('https://blog.com/posts')
// Get all article links
article_links = mcp_playwright.query_selector_all('article a[href]')
// Process each
for (link in article_links) {
// Enter detail page
mcp_playwright.click(link)
mcp_playwright.wait_for_load_state('networkidle')
// Extract content
text = mcp_playwright.get_text('article')
// Return to list
mcp_playwright.go_back()
mcp_playwright.wait_for_load_state('networkidle')
}
Use for: Multi-page results, forums, archives
Process:
1. Process current page
2. Find "Next" button
3. Click and repeat
4. Stop when no more pages
MCP Commands:
while (true) {
// Process current page
articles = mcp_playwright.query_selector_all('article')
for (article in articles) {
// Extract content
}
// Check for next page
next_button = mcp_playwright.query_selector('a.next, [rel="next"]')
if (!next_button) break
// Go to next page
mcp_playwright.click(next_button)
mcp_playwright.wait_for_load_state('networkidle')
}
Use for: Social media, modern blogs, dynamic content
// Scroll and load pattern
current_height = 0
while (true) {
// Get current height
new_height = mcp_playwright.evaluate('document.body.scrollHeight')
if (new_height == current_height) break
// Scroll to bottom
mcp_playwright.evaluate('window.scrollTo(0, document.body.scrollHeight)')
mcp_playwright.wait_for_timeout(2000) // Wait for content load
current_height = new_height
}
// Then extract all loaded content
all_articles = mcp_playwright.query_selector_all('article')
// Search results
list_selector: '.blog_list li'
link_selector: '.api_txt_lines.total_tit'
content_selector: '.se-main-container'
comment_selector: '.u_cbox_contents'
// Blog specific
blog_content: '#postViewArea, .se-main-container'
blog_title: '.se-title-text, .pcol1'
// Search results
list_selector: '.list_info'
link_selector: '.f_link_b, .tit_main'
content_selector: '.article_view'
// Tistory blogs
tistory_content: '.entry-content, .article-view'
tistory_comments: '.comment-list'
article_list: '.wrap_article_list li'
article_link: 'a.link_post'
article_content: '.wrap_body'
article_list: 'article'
article_link: 'h2 a, h3 a'
article_content: 'section.pw-post-body'
clap_count: '[aria-label*="clap"]'
post_list: '[data-testid="post-container"]'
post_content: '[data-click-id="text"]'
comments: '.Comment'
upvotes: '[aria-label*="upvote"]'
// Works on most blogs
article_containers: 'article, .post, .entry, .blog-post'
title_selectors: 'h1, .title, .post-title, .entry-title'
content_selectors: 'main, .content, .post-content, .entry-content'
comment_selectors: '.comments, .comment-list, #comments'
author_selectors: '.author, .by-author, .writer, [rel="author"]'
date_selectors: 'time, .date, .published, .post-date'
| Scenario | Pattern | Depth | Example |
|---|---|---|---|
| "๋ด์ค ํค๋๋ผ์ธ ํ์ด๋ด" | List-Detail | Quick | 50 titles |
| "๋ธ๋ก๊ทธ ๊ธ 10๊ฐ ์ฝ์ด์ค" | List-Detail | Standard | Full content |
| "ํฌ๋ผ ๋๊ธ๊น์ง ๋ถ์ํด" | List-Detail | Deep | With comments |
| "๋ชจ๋ ํ์ด์ง ๋ค ๋ด" | Pagination | Standard | All pages |
| "์ธ์คํ ํผ๋ ์ญ ๋ด" | Infinite Scroll | Quick | Social media |
1. Try specific selector first
โ '.se-main-container' (Naver specific)
2. Fallback to semantic HTML
โ 'article', 'main'
3. Try common class patterns
โ '.content', '.post-content'
4. Last resort: get all text
โ 'body' (then clean up)
// Navigation
mcp_playwright.navigate(url)
mcp_playwright.go_back()
mcp_playwright.go_forward()
mcp_playwright.reload()
// Element Selection
mcp_playwright.query_selector(selector) // First match
mcp_playwright.query_selector_all(selector) // All matches
// Interaction
mcp_playwright.click(element_or_selector)
mcp_playwright.type(selector, text)
mcp_playwright.scroll_to(x, y)
// Content Extraction
mcp_playwright.get_text(selector)
mcp_playwright.get_attribute(selector, attribute)
mcp_playwright.get_url()
mcp_playwright.get_title()
// Waiting
mcp_playwright.wait_for_selector(selector)
mcp_playwright.wait_for_load_state('networkidle')
mcp_playwright.wait_for_timeout(milliseconds)
// JavaScript Execution
mcp_playwright.evaluate(javascript_code)
// User: "๋ค์ด๋ฒ ๋ด์ค ์ ๋ชฉ๋ง ๋น ๋ฅด๊ฒ ํ์ด์ค"
mcp_playwright.navigate('https://news.naver.com')
headlines = mcp_playwright.query_selector_all('.news_tit')
for (headline in headlines.slice(0, 30)) {
title = mcp_playwright.get_text(headline)
// Store title
}
// User: "์ด ๋ธ๋ก๊ทธ ์ต์ ๊ธ 5๊ฐ ๋๊ธ๊น์ง ์์ธํ ๋ด์ค"
mcp_playwright.navigate('https://blog.example.com')
posts = mcp_playwright.query_selector_all('.post-link')
for (post in posts.slice(0, 5)) {
mcp_playwright.click(post)
// Get everything
title = mcp_playwright.get_text('h1')
content = mcp_playwright.get_text('article')
author = mcp_playwright.get_text('.author')
date = mcp_playwright.get_text('.date')
// Get all comments
comments = mcp_playwright.query_selector_all('.comment')
for (comment in comments) {
text = mcp_playwright.get_text(comment)
}
mcp_playwright.go_back()
}
// User: "๋ ๋ง ์ค๋ ๋ ์ ์ฒด ํ ๋ก ๋ถ์ํด์ค"
mcp_playwright.navigate(reddit_url)
// Main post
main_post = mcp_playwright.get_text('[data-click-id="text"]')
upvotes = mcp_playwright.get_text('[aria-label*="upvote"]')
// All comments with nested replies
all_comments = mcp_playwright.query_selector_all('.Comment')
for (comment in all_comments) {
text = mcp_playwright.get_text(comment)
// Parse nested structure
}
Selector Not Found
// Try multiple selectors
content = mcp_playwright.query_selector('article')
|| mcp_playwright.query_selector('main')
|| mcp_playwright.query_selector('.content')
|| mcp_playwright.query_selector('body')
Dynamic Content Not Loaded
// Wait strategies
mcp_playwright.wait_for_load_state('networkidle')
mcp_playwright.wait_for_selector('.content', timeout=10000)
mcp_playwright.wait_for_timeout(2000) // Last resort
Navigation Failed
try {
mcp_playwright.go_back()
} catch {
// Fallback: navigate directly
mcp_playwright.navigate(list_page_url)
}
User Request
โ
Analyze Keywords โ Determine Depth (Quick/Standard/Deep)
โ
Identify Site Type โ Choose Selectors
โ
Select Pattern โ (List-Detail/Pagination/Scroll)
โ
Execute with MCP Commands
โ
Handle Errors โ Fallback Strategies
For detailed patterns and selectors by site type, see: