J0ker98
J0ker98

Reputation: 457

Convert CSS Selectors to XPath selector in python without external libraries

Is it possible to convert complex CSS Selectors such as:

@[class="maintitle"] > .main-wrap #myid > .h1 bold

To XPath in Python 3 without using external libraries? Or with regex?

I'm currently able to convert

@[class="maintitle"]

to "//*[contains(@class,'maintitle')]" but cannot manage to create a global rule to convert these more complex selectors. Is it even possbile?

Edit: I can't use cssselect.

Upvotes: 0

Views: 205

Answers (2)

dharma G
dharma G

Reputation: 1

the best way would be using lxml:

You can pass "//" as a param to XPath(GenericTranslator().css_to_xpath(css_selector)

something like this XPath(GenericTranslator().css_to_xpath(css_selector,"//") to avoid descendant-or-self:: at the beginning

Upvotes: 0

Andersson
Andersson

Reputation: 52665

Try below XPath

//*[@class="maintitle"]/*[contains(@class, "main-wrap")]//*[@id="myid"]/*[contains(@class="h1")]//bold

If you need tool that can convert CSS to XPath for you, you can try lxml:

from cssselect import GenericTranslator
from lxml.etree import XPath

css_selector = """[class="maintitle"] > .main-wrap #myid > .h1 bold"""
print(XPath(GenericTranslator().css_to_xpath(css_selector)))

Output (looks weird, but...):

descendant-or-self::*[@class = 'maintitle']/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' main-wrap ')]/descendant-or-self::*/*[@id = 'myid']/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' h1 ')]/descendant-or-self::*/bold

Note that you might also need to add // at the beggining as:

print("//" + str(XPath(GenericTranslator().css_to_xpath(css_selector))))

Upvotes: 2

Related Questions