SCRAPE_BY_CSS_PATH
Scrape content from a webpage using a CSS selector.
=SCRAPE_BY_CSS_PATH(url, selector, [attribute], [renderJs])Returns: string or 2D array (multiple matches returned as separate rows)
Overview
SCRAPE_BY_CSS_PATH extracts content from any webpage using standard CSS selectors, the same query syntax used by web developers to style HTML elements. Point it at a URL, provide a CSS selector like ".price", "#title", or "h1", and it returns the matching text content directly into your spreadsheet. When multiple elements match the selector, each result is returned as a separate row, making it easy to pull entire lists of products, links, or data points in a single call.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | The full URL of the webpage to scrape (must include https:// or http://). |
selector | string | Yes | CSS selector targeting the element(s) to extract. Supports standard CSS syntax including classes (.class), IDs (#id), elements (h1), attributes ([data-price]), combinators (div > p), and pseudo-selectors (li:first-child). |
attribute | string | No | Optional HTML attribute to extract instead of text content. Common values: "href" (link URLs), "src" (image/script sources), "alt" (image alt text), "data-*" (custom data attributes), "content" (meta tag values). |
renderJs | boolean | No | Optional. Set to TRUE to render JavaScript before scraping. Required for single-page applications and dynamically loaded content. Slower and uses more credits than standard mode. |
Examples
Extract the main heading from a page
Returns the text content of the first h1 element on the page. Useful for quickly checking page titles across a list of URLs.
=SCRAPE_BY_CSS_PATH("https://example.com", "h1")Output
Example DomainGet all navigation link URLs
Extracts the href attribute from every anchor tag inside a nav element. Returns multiple rows if there are multiple links.
=SCRAPE_BY_CSS_PATH("https://example.com", "nav a", "href")Output
| /about |
| /products |
| /blog |
| /contact |
Scrape product prices from an e-commerce page
Targets price elements nested inside product cards. Returns all matching prices as separate rows for easy comparison.
=SCRAPE_BY_CSS_PATH("https://store.example.com/shoes", ".product-card .price")Output
| $89.99 |
| $129.00 |
| $64.50 |
| $199.99 |
Extract meta description for SEO audit
Uses an attribute selector to find the meta description tag and extracts its content attribute. Essential for SEO audits at scale.
=SCRAPE_BY_CSS_PATH("https://example.com", "meta[name='description']", "content")Output
This is the meta description of the example page.Scrape JavaScript-rendered product listings
Enables JavaScript rendering to scrape a single-page application. The empty third parameter skips the attribute argument, and TRUE activates the headless browser.
=SCRAPE_BY_CSS_PATH("https://spa-store.example.com", ".item-title", , TRUE)Output
| Wireless Headphones |
| USB-C Hub |
| Laptop Stand |
Use Cases
Competitor Price Monitoring
Set up a spreadsheet that scrapes competitor product pages daily using CSS selectors targeting price elements. Track pricing trends over time and get alerts when competitors change their pricing strategy.
SEO Title and Meta Tag Auditing
Audit hundreds of pages by scraping their title tags, meta descriptions, and heading structures using CSS selectors. Identify missing or duplicate meta data, overly long titles, and pages lacking proper heading hierarchy.
Job Listing Aggregation
Scrape job boards and company career pages to aggregate job listings into a single spreadsheet. Extract job titles, locations, salary ranges, and application links using targeted CSS selectors for each data point.
Real Estate Listing Tracking
Monitor property listing sites by scraping prices, addresses, square footage, and listing dates. Build a comprehensive market analysis spreadsheet that updates with current inventory and pricing data.
Academic Research Data Collection
Collect structured data from research databases, government portals, and institutional websites. Scrape publication titles, author names, dates, and abstracts into organized spreadsheets for literature reviews.
Social Proof and Review Monitoring
Track product reviews and ratings across multiple platforms by scraping review scores, review counts, and star ratings. Aggregate data across Amazon, G2, Trustpilot, and industry-specific review sites.
Pro Tips
Use the browser DevTools "Copy selector" feature as a starting point, but simplify the selector to make it more resilient to page changes. A selector like ".product-price" is more stable than "div.container > div:nth-child(3) > span.product-price".
Combine with ARRAYFORMULA to scrape the same selector across multiple URLs listed in a column. For example, =ARRAYFORMULA(SCRAPE_BY_CSS_PATH(A2:A10, "h1")) will extract the h1 from each URL in cells A2 through A10.
When scraping e-commerce sites, target data attributes like [data-price] or [data-product-id] rather than visual elements, as data attributes are more stable and contain cleaner values.
Test your CSS selector in the browser console first using document.querySelectorAll("your-selector") to verify it matches the right elements before using it in the spreadsheet.
For pages that load content in stages, the renderJs option waits for the initial page load event. If content loads after additional user interactions (like clicking a "Load More" button), it may not be captured.
By default the function returns the visible text content of matched elements. You can optionally specify an attribute parameter to extract specific HTML attributes instead, such as "href" for link URLs, "src" for image sources, or any custom data attribute. This makes it incredibly versatile for tasks like building link inventories, collecting image URLs, or extracting structured data attributes.
For modern websites that rely heavily on JavaScript to render their content (single-page applications, React/Vue/Angular sites, dynamically loaded product catalogs), enable the renderJs parameter. This instructs the scraper to use a headless browser that fully executes JavaScript before extracting content, ensuring you capture data that would otherwise be invisible in the raw HTML source. Note that JavaScript rendering is slower and consumes more credits, so only enable it when the standard mode returns empty or incomplete results.
SCRAPE_BY_CSS_PATH is ideal for SEO audits, competitive research, price monitoring, content aggregation, and any workflow where you need to pull structured data from the web into Google Sheets without writing code.
Common Errors
No matches foundCause: The CSS selector does not match any elements on the page. This often happens when the page content is loaded via JavaScript but renderJs is not enabled, or the selector has a typo.
Fix: Verify the selector works in the browser DevTools console with document.querySelectorAll("your-selector"). If elements exist in the browser but the function returns nothing, enable renderJs by setting the fourth parameter to TRUE.
Error: URL and selector are requiredCause: One or both of the required parameters (url and selector) are empty or missing.
Fix: Ensure both the URL and CSS selector are provided. The URL must be a full address including the protocol (https:// or http://). Check that cell references are not pointing to empty cells.
Error: Failed to fetch URLCause: The target website blocked the request, the URL is invalid, the server is down, or a network timeout occurred.
Fix: Verify the URL is accessible in your browser. Some websites block automated requests; try a different page on the same site. Check that the URL includes the protocol (https://). If the site requires JavaScript, try enabling renderJs.
Frequently Asked Questions
Open the target webpage in Chrome or Firefox, right-click the element you want to scrape, and select "Inspect" or "Inspect Element." This opens the browser developer tools with the HTML element highlighted. You can right-click the highlighted element in the Elements panel and choose "Copy > Copy selector" to get an auto-generated CSS selector. For more reliable selectors, look for unique class names or IDs on the element. For example, if you see <div class="product-price">$29.99</div>, your selector would be ".product-price". Avoid overly specific auto-generated selectors with many nested elements, as these break easily when the page layout changes.
By default, SCRAPE_BY_CSS_PATH returns the visible text content of the matched element, which is what a user sees on the page. When you specify an attribute parameter, it extracts the value of that HTML attribute instead. For example, an anchor tag <a href="https://example.com" class="link">Click Here</a> would return "Click Here" without an attribute, but would return "https://example.com" if you set the attribute to "href". Common attributes include "href" for links, "src" for images, "alt" for image descriptions, "content" for meta tags, and any "data-*" custom attributes.
Enable renderJs when the content you want to scrape is loaded dynamically via JavaScript. Signs that you need it include: the function returns empty results or "No matches found" even though you can see the content in your browser; the website is a single-page application built with React, Vue, Angular, or similar frameworks; the content loads after scrolling or after a delay; or the page shows a loading spinner before content appears. Standard mode is faster and cheaper, so try without renderJs first and only enable it if needed.
Each call to SCRAPE_BY_CSS_PATH targets one CSS selector, but that selector can match multiple elements of the same type (all returned as rows). To scrape different types of elements (e.g., both titles and prices), make separate function calls with different selectors. You can combine CSS selectors with commas to match multiple element types in one call, for example ".title, .price", but the results will be interleaved. For structured data extraction where you need to keep titles paired with their prices, use separate columns with one selector per column.
The function returns up to 500 matched elements per call. If the page contains more than 500 matching elements, only the first 500 are returned. For most use cases this is more than sufficient. If you need to scrape pages with extremely large numbers of elements, consider using more specific CSS selectors to narrow down the results, or use pagination parameters if the target website supports them.
SCRAPE_BY_CSS_PATH accesses pages as an anonymous visitor without cookies or session data. It cannot scrape content behind login walls, paywalls, or authentication barriers. The scraper does not support sending cookies, headers, or credentials. For authenticated content, you would need to find a public API for that service or use an alternative data source. Some websites offer public JSON APIs or RSS feeds that may provide the data you need without authentication.
The scraper makes HTTP requests similar to a web browser and does not automatically check or enforce robots.txt rules. However, you should review and respect the target website's robots.txt file and terms of service before scraping. Excessive scraping can lead to your IP being blocked. Use the function responsibly, avoid scraping at high frequency, and respect rate limits. Unlimited Sheets applies its own rate limiting to prevent abuse.
SCRAPE_BY_CSS_PATH is a standalone function that replaces the need for IMPORTXML or IMPORTHTML in many cases. Unlike IMPORTXML, it uses CSS selectors (which are more intuitive for most users) rather than XPath expressions. Unlike IMPORTHTML, it can target any element on the page, not just tables and lists. You can use SCRAPE_BY_CSS_PATH alongside native Google Sheets functions in the same spreadsheet without conflicts.
Related Functions
Start using SCRAPE_BY_CSS_PATH today
Install Unlimited Sheets to get SCRAPE_BY_CSS_PATH and 41 other powerful functions in Google Sheets.