diff --git a/requests_html.py b/requests_html.py
index 0745edb..4c382e1 100644
--- a/requests_html.py
+++ b/requests_html.py
@@ -103,7 +103,6 @@ class BaseParser:
See W3School's `CSS Selectors Reference `_ for more details.
-
If ``first`` is ``True``, only returns the first :class:`Element ` found."""
encoding = _encoding or self.encoding
@@ -115,12 +114,27 @@ class BaseParser:
return _get_first_or_list(elements, first)
def xpath(self, selector: str, first: bool = False, _encoding: str = None):
- """Given an XPath selector, returns a list of :class:`Element ` objects.
+ """Given an XPath selector, returns a list of
+ :class:`Element ` objects.
- See W3School's `XPath Examples `_ for more details.
+ If a sub-selector is specified (e.g. ``//a/@href``), a simple
+ list of results is returned.
- If ``first`` is ``True``, only returns the first :class:`Element ` found."""
- c = [Element(element=e, url=self.url, default_encoding=_encoding or self.encoding) for e in self.lxml.xpath(selector)]
+ See W3School's `XPath Examples
+ `_
+ for more details.
+
+ If ``first`` is ``True``, only returns the first
+ :class:`Element ` found.
+ """
+ selected = self.lxml.xpath(selector)
+ c = []
+ for selection in selected:
+ if not isinstance(selection, etree._ElementUnicodeResult):
+ element = Element(element=selection, url=self.url, default_encoding=_encoding or self.encoding)
+ else:
+ element = selection
+ c.append(element)
return _get_first_or_list(c, first)
diff --git a/tests/test_requests_html.py b/tests/test_requests_html.py
index c2c9ad7..5780bde 100644
--- a/tests/test_requests_html.py
+++ b/tests/test_requests_html.py
@@ -59,6 +59,9 @@ def test_xpath():
html = r.html.xpath('/html', first=True)
assert 'no-js' in html.attrs['class']
+ a_hrefs = r.html.xpath('//a/@href')
+ assert '#site-map' in a_hrefs
+
def test_html_loading():
doc = """"""
@@ -77,4 +80,4 @@ def test_anchor_links():
if __name__ == '__main__':
- test_anchor_links()
+ test_xpath()