Free tools Windows power users keep installed
One-click scans. No signup required.
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:
#1 Best Overall
- 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.
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
- 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:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →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
- 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.
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
- 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.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →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.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.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteBest Value
- 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.
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.
Quick Recap
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.

