Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the CSS negation selector :not([attribute]) to select elements where an attribute is absent. For example, $('li:not([data-id])') returns only <li> elements that do not contain a data-id attribute. When you already have a Cheerio collection, use .not('[attribute]') instead.

Select elements with an absent attribute

Cheerio uses CSS selectors, the same selector syntax used by document.querySelectorAll. An attribute-presence selector such as [data-id] matches an element whenever the attribute exists. Prefixing it with :not() reverses that test.

const cheerio = require('cheerio');

const html = `
  <ul>
    <li>A</li>
    <li data-id="2">B</li>
    <li data-id="">C</li>
  </ul>
`;

const $ = cheerio.load(html);
const withoutId = $('li:not([data-id])');

console.log(withoutId.length); // 1
console.log(withoutId.text()); // A

The selector is read as “find li elements that do not match [data-id].” It excludes both data-id="2" and data-id="", because both elements have the attribute.

Apply the test to any element type

To match any element with no data-test attribute, omit the element name:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
const unmarked = $(':not([data-test])');

This selects every matching element in the current document, not just one tag name. Use a specific element name when possible; it makes the extraction intent clearer and reduces accidental matches. A selector such as * :not([data-test]) adds a descendant relationship and therefore has a different meaning: it targets elements below another element, rather than simply testing every element in the current root.

Common selectors for missing attributes

Requirement Selector What it matches
Buttons without disabled button:not([disabled]) Buttons on which the attribute is absent
Links without href a:not([href]) Anchors with no href attribute
Elements without data-test :not([data-test]) Any element lacking that attribute
Elements missing two attributes a:not([href]):not([target]) Anchors where both attributes are absent
Existing collection, remove marked elements $('.item').not('[data-test]') .item elements that do not have data-test

Require several attributes to be absent

Chain separate negations when every listed attribute must be missing. For example:

const plainLinks = $('a:not([href]):not([target])');

Each condition is cumulative, so a link with either href or target is excluded. This differs from a comma-separated selector:

const eitherMissing = $('a:not([href]), a:not([target])');

The comma means “match either selector.” Consequently, a link can still have one of the attributes and be included because it satisfies the other condition. Use chained :not() clauses for an “all absent” requirement; use commas only when alternatives are intended.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use .not() after creating a selection

Cheerio’s traversal API provides .not(), which removes elements matching a selector from an existing collection. It is useful when the initial collection expresses the scope and the second selector expresses the exclusion.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
const items = $('.item');
const untaggedItems = items.not('[data-test]');

untaggedItems.each((index, element) => {
  console.log($(element).text().trim());
});

These two forms normally produce the same result:

$('.item:not([data-test])');
$('.item').not('[data-test]');

Prefer the CSS form when the complete condition is easy to read in one selector. Prefer .not() when you already have a collection, build the scope dynamically, or want the exclusion to be visually separate from the initial query.

Distinguish absent, empty and whitespace-only values

Attribute presence is not the same as a useful value. The selector [data-id] matches both data-id="2" and data-id="". Therefore :not([data-id]) means strictly “the attribute does not exist,” not “the attribute is empty or unusable.”

If both absence and an exactly empty value should count, use alternatives:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const missingOrEmpty = $('li:not([data-id]), li[data-id=""]');

For several value rules, JavaScript filtering is usually clearer. This example treats missing, empty and whitespace-only values as missing:

const needsId = $('li').filter((index, element) => {
  const value = $(element).attr('data-id');
  return value == null || value.trim() === '';
});

Choose the normalization deliberately. Trimming may be correct for an identifier supplied by users, but it may be wrong when whitespace has semantic meaning in the source format. Cheerio’s parsed attribute value and your application’s validation rules determine what “empty” means.

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Scope selectors correctly with find()

Selectors passed to find() are evaluated relative to the current Cheerio selection. A query that works at the document root can return zero results when the root has already been narrowed.

const cards = $('.card');
const untaggedTitles = cards.find('h2:not([data-test])');

Here the selector checks only descendants of .card, not every h2 in the document. If the result is unexpectedly empty or too large, inspect each stage:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
console.log('cards:', cards.length);
console.log('titles:', untaggedTitles.length);

Also check whether the desired element is the current selection itself rather than a descendant. find() searches inside the selection; it does not test the selected root. In that case, use .filter(':not([data-test])') or .not('[data-test]').

Cheerio sees supplied markup, not a live browser page

Cheerio parses the HTML or XML tree you provide. It is not a browser: it does not visually render a page, load external resources or execute JavaScript. If a browser script adds data-id after page load, that attribute is invisible to Cheerio unless you first supply the post-script markup. Likewise, Cheerio does not apply CSS, so visually hidden elements remain in the selection.

When scraping a URL, obtain the HTML with an HTTP client, then pass the response body to Cheerio. If the site builds the relevant attributes in the browser, use a browser automation tool to render the page and export its resulting HTML before running the selector. Do not interpret an empty Cheerio result as proof that the live page lacks the element; it may only be absent from the input string.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

Complete extraction example

This script collects only product cards whose data-sku attribute is genuinely absent, while separately reporting cards with an empty value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const cheerio = require('cheerio');

const html = `
  <section class="products">
    <article class="product"><h2>Notebook</h2></article>
    <article class="product" data-sku="A-10"><h2>Pen</h2></article>
    <article class="product" data-sku=""><h2>Folder</h2></article>
  </section>
`;

const $ = cheerio.load(html);
const products = $('.products .product');
const withoutSku = products.not('[data-sku]');
const emptySku = products.filter((i, el) => $(el).attr('data-sku') === '');

console.log('Absent:', withoutSku.map((i, el) => $('h2', el).text()).get());
console.log('Empty:', emptySku.map((i, el) => $('h2', el).text()).get());

The output separates structural absence from an explicitly present empty attribute, which prevents accidental data-quality assumptions.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot unexpected results

The selector returns elements that have an empty attribute

That is expected for a presence test. :not([data-id]) excludes only elements where the attribute exists. Add a value check or a callback filter if empty values should also be removed.

No elements are returned

  • Log the input HTML and confirm the attribute spelling, case and hyphenation.
  • Check the current root when using find(); the selector is relative to it.
  • Verify that the attribute is present in the supplied markup rather than injected by client-side JavaScript.
  • Confirm that the initial selector is not already excluding the elements you expect to test.

Too many elements are returned

  • Replace a broad :not([attribute]) with a tag or class-qualified selector.
  • Check whether a descendant selector such as * :not(...) was added unintentionally.
  • Inspect nested content and duplicate template elements in the parsed tree.

Results differ after a Cheerio upgrade

Selector behavior depends on the Cheerio/css-select versions installed by your project. Pin and document the versions used by production, run a small fixture containing absent, empty and populated attributes, and consult the release documentation before changing a complex selector.

The page looks different from the extracted result

Cheerio does not render CSS or execute scripts. Compare the raw HTML supplied to cheerio.load() with the browser’s post-render DOM. A browser screenshot or inspector view is not automatically the same tree Cheerio parses.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

Performance and maintainability

Keep the query narrow: $('.catalog .item:not([data-id])') communicates scope and avoids walking unrelated nodes. If you need several related tests, select the smallest useful collection once and apply .not() or .filter() to it. Use a selector for straightforward structural conditions and a callback for normalization, logging or cross-attribute rules. Store the resulting collection before iterating so the same query is not repeatedly evaluated in a loop.

For large documents, avoid broad document-wide selectors when a section root is available. Measure the whole pipeline if performance matters: network retrieval, parsing, selection and serialization can dominate the selector itself.

Or skip the browser setup

If your goal is to obtain clean page markup or an image before inspecting elements, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and can capture PNG, JPEG, WebP or PDF; it is not a replacement for Cheerio’s HTML parser, but it can remove browser-capture setup from visual verification and agent workflows.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for the request options. Before capture, cookie and consent banners, newsletter popups and chat widgets can be removed; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server includes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month without a card, and paid plans start at $5 for 3,000 shots. Sign up free for ScreenshotNeo.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Practical decision guide

  • Use :not([attribute]) when you need a concise structural selector at the point of selection.
  • Use .not('[attribute]') when you already have a scoped collection.
  • Use chained negations when all listed attributes must be absent.
  • Use .filter() when missing, empty and whitespace-only values need custom definitions.
  • Use rendered browser HTML first when scripts create the attributes you need to inspect.

Frequently Asked Questions

Does :not([data-id]) match an element with data-id=""?

No. The attribute is present, even though its value is empty. Add an empty-value alternative or use a callback filter if empty values should count as missing.

Can I combine an attribute-negation selector with a class?

Yes. For example, $('.card:not([data-id])') limits the test to elements having the card class.

Will Cheerio detect attributes added by a framework after the initial HTML response?

No. Cheerio examines only the markup passed to it and does not execute client-side JavaScript. Supply rendered HTML from a browser process if those attributes are required.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.