Very often I see that calls to xpath could as well be replaced by calls to findall, when can this be done? What is the main differences between the two functions? The first argument to path findall is a path, while to xpath the first argument _path is an xpath. lxml docs for findall(): https://lxml.de/apidoc/lxml.etree.html#lxml.etree._Element.findall findall(self, path, namespaces=None): """Finds all matching subelements, by tag name or path. The optional namespaces argument accepts a prefix-to-namespace mapping that allows the usage of XPath prefixes in the path expression.""" lxml docs for xpath(): https://lxml.de/apidoc/lxml.etree.html#lxml.etree.XPath xpath(self, _path, namespaces=None, extensions=None, smart_strings=True, **_variables) """Evaluate an xpath expression using the element as context node.""" However most of the arguments are not documented what they do. And a non-listed argument error_log is supplied with and empty description. This seems to be the specification of an xpath: https://www.w3.org/TR/xpath-31/ But what is the path object supplied to findall? I found this old pyton3 documentation talking about a limited API, is it related? https://docs.python.org/2/library/xml.etree.elementtree.html#xpath-support Continue reading...