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()