diff --git a/docs/topics/selectors.rst b/docs/topics/selectors.rst index 0d82494a4..bd4135b34 100644 --- a/docs/topics/selectors.rst +++ b/docs/topics/selectors.rst @@ -149,6 +149,11 @@ It returns ``None`` if no element was found: >>> response.xpath('//div/[id="not-exists"]/text()').extract_first() is None True +A default return value can be provided as an argument, to be used instead of ``None``: + + >>> sel.xpath('//div/[id="not-exists"]/text()').extract_first(default='not-found') + 'not-found' + Notice that CSS selectors can select text or attribute nodes using CSS3 pseudo-elements:: diff --git a/scrapy/selector/unified.py b/scrapy/selector/unified.py index 164ded2bf..0a2f40c6a 100644 --- a/scrapy/selector/unified.py +++ b/scrapy/selector/unified.py @@ -184,9 +184,11 @@ class SelectorList(list): def extract(self): return [x.extract() for x in self] - def extract_first(self): + def extract_first(self, default=None): for x in self: return x.extract() + else: + return default @deprecated(use_instead='.extract()') def extract_unquoted(self): diff --git a/tests/test_selector.py b/tests/test_selector.py index a46f7635c..09dbe6086 100644 --- a/tests/test_selector.py +++ b/tests/test_selector.py @@ -73,6 +73,14 @@ class SelectorTestCase(unittest.TestCase): self.assertEqual(sel.xpath('/ul/li[@id="doesnt-exist"]/text()').extract_first(), None) + def test_extract_first_default(self): + """Test if extract_first() returns default value when no results found""" + body = '