To use a CSS Selector in n8n, you’ll primarily work with two nodes: the HTTP Request node to fetch a webpage’s HTML code, and the HTML node to parse it. Within the HTML node’s ‘Extract HTML Content’ operation, you define a CSS selector—a specific path that tells n8n exactly which element(s) to grab from the page. This powerful feature allows you to transform unstructured website content into structured JSON data, perfect for automating tasks like price monitoring, content aggregation, and lead generation.
So, What Exactly is a CSS Selector, Anyway?
Think of a webpage as a big, busy city. If you want to find a specific building, you need an address, right? A CSS selector is that address for data. It’s a pattern used to select specific elements on an HTML page. Instead of telling a friend to find “the blue house on the corner,” you give n8n a precise address like div.house#main-residence
, and it goes directly there.
Let’s be honest, you don’t need to be a front-end developer to use them, but knowing the basics is a game-changer. Here are the most common types you’ll encounter:
- Element Selectors: The simplest type.
p
selects all paragraphs,h2
selects all level-2 headings, anda
selects all links. - Class Selectors: These start with a period (
.
). If you want to grab an element with the classproduct-price
, your selector is.product-price
. - ID Selectors: These start with a hash (
#
). IDs are meant to be unique on a page, making them a very reliable way to select something. For an element with the IDmain-content
, you’d use#main-content
.
These can be combined for even more precision, but we’ll get to that in a bit.
Your Toolkit: The HTTP Request and HTML Nodes
Your web scraping journey in n8n almost always starts with the same dynamic duo.
- The HTTP Request Node: This is your scout. You give it a URL, and it goes out and brings back the raw HTML source code of that page. It’s the equivalent of your browser asking a server for a webpage before it displays it.
- The HTML Node: This is your interpreter. It takes the raw HTML from the HTTP Request node and makes it parsable. Its most powerful operation is ‘Extract HTML Content’.
When you configure the HTML node, you’ll focus on the ‘Extraction Values’ section. For each piece of data you want, you specify:
- Key: The name you want to give the extracted data in your JSON output (e.g.,
productName
). - CSS Selector: The address for the data you want.
- Return Value: What you want to get from that address. Do you want the
Text
inside the element? The rawHTML
? Or a specificAttribute
like thehref
from a link orsrc
from an image?
Choosing the right ‘Return Value’ is critical. Grabbing the text from a price element is great, but for a product image, you need its src
attribute, not the non-existent text inside the <img>
tag.
Finding the Perfect n8n CSS Selector in Your Browser
So, how do you find the address for the data you want? You don’t have to guess! Your web browser has a built-in map called Developer Tools.
Here’s my go-to method that works every time:
- Go to the webpage you want to scrape.
- Right-click on the exact piece of data you want (like a product price or a headline).
- Select Inspect from the context menu. This will open up a panel showing the page’s HTML, with the element you clicked on conveniently highlighted.
- Right-click on that highlighted line of code in the inspector.
- Navigate to Copy > Copy selector.
Voila! You now have a CSS selector copied to your clipboard, ready to be pasted directly into the CSS Selector
field in your n8n HTML node.
A word of caution: Browser-generated selectors can sometimes be overly specific and fragile, like body > div:nth-child(2) > main > div:nth-child(4) > p
. If the website’s layout changes even slightly, this selector might break. I always recommend looking at the copied selector and seeing if you can simplify it. Is there a unique class or ID you can use instead, like .product-price-display
? A simpler, more semantic selector is always more robust.
A Real-World Example: Scraping Blog Post Titles
Let’s put this into practice. Imagine we want to get a list of all the blog post titles from a site’s main blog page. The titles are all <h2>
elements with a class of post-title
.
-
Workflow Setup:
- HTTP Request Node: Set the URL to the blog page.
- HTML Node: Connect it to the output of the HTTP Request node.
-
Configuring the HTML Node:
- Operation:
Extract HTML Content
. - Source Data:
JSON
(the default is usually correct). - JSON Property:
data
(assuming the HTML is in thedata
field from the HTTP Request node).
- Operation:
-
Setting up the Extraction Values:
- Key:
postTitle
- CSS Selector:
h2.post-title
(This targets allh2
elements that also have thepost-title
class). - Return Value:
Text
- Return Array: Toggle this ON. This is crucial! It tells n8n to find all matching elements and return them in an array, not just the first one it finds.
- Key:
When you execute this, you won’t get just one title. You’ll get a clean JSON object with a key named postTitle
containing an array of every single blog post title on the page. How cool is that?
Common Pitfalls and Advanced Selectors
As you get more adventurous, you might run into a few tricky situations. Let’s tackle the most common ones.
The Case of the Spaced-Out Class Name
I’ve seen this trip up so many people in the community forums. You inspect an element and see class="card featured"
. So you try to use .card featured
as your selector, but it fails. Why? Because a space in a CSS selector means “descendant.” You just told n8n to look for an element inside .card
that is a <featured>
tag (which doesn’t exist).
The correct way to select an element that has both classes is to chain them without a space: .card.featured
.
Advanced Selector Cheat Sheet
Sometimes, you need to get even more specific. Here’s a table of more advanced selectors to add to your arsenal:
Selector | What it Does | Example Use Case |
---|---|---|
element[attribute] |
Selects based on the presence of an attribute. | img[alt] (Find all images that have alt text.) |
element[attribute="value"] |
Selects based on an exact attribute value. | a[target="_blank"] (Find all links opening in a new tab.) |
parent > child |
Selects a direct child of a parent element. | ul.main-menu > li (Get only top-level menu items.) |
element:first-child |
Selects the first element among its siblings. | tr:first-child (Get the header row of a table.) |
element:nth-child(n) |
Selects the nth element among its siblings. | div.product-card:nth-child(3) (Get the third product card.) |
Mastering the n8n CSS selector is a true automation superpower. It effectively turns the entire web into a potential API for your workflows. Don’t be afraid to experiment. Open the DevTools, play around with selectors, and see what you can build. You’ll be surprised at how quickly you can start pulling valuable data to fuel your most creative automations.