Skip to content

Support ID selectors inside :has() - #187

Closed
yetval wants to merge 1 commit into
scrapy:masterfrom
yetval:has-id-selector
Closed

Support ID selectors inside :has()#187
yetval wants to merge 1 commit into
scrapy:masterfrom
yetval:has-id-selector

Conversation

@yetval

@yetval yetval commented Sep 1, 2026

Copy link
Copy Markdown

parse_relative_selector() only accepts IDENT, ., and * tokens in a :has() argument, so any ID selector raises:

>>> parse("div:has(> #foo)")
SelectorSyntaxError: Expected an argument, got <HASH 'foo' at 10>

This works in browsers, which implement the full relative-selector grammar.

This PR adds HASH to the accepted token types in the argument loop. No changes are needed in the translation layer—the token reparse and XPath translation already handle Hash nodes, escaped identifiers included:

>>> HTMLTranslator().css_to_xpath(r"div:has(> #foo\.bar)")
"descendant-or-self::div[./*[@id = 'foo.bar']]"

Tests added for parsing, specificity, repr round-trip, XPath translation, and the error case (:has(a #b) still rejects the descendant combinator).

Downstream report: D4Vinci/Scrapling#433

@wRAR

wRAR commented Sep 1, 2026

Copy link
Copy Markdown
Member

This should be fixed by #179.

@yetval

yetval commented Sep 1, 2026

Copy link
Copy Markdown
Author

This should be fixed by #179.

Seems like I missed that I will close this pr in favor of it.

@yetval yetval closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants