Reputation: 457
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
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
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