Skip to content

Commit

Permalink
Merge pull request #107 from scrapy/add-attrs
Browse files Browse the repository at this point in the history
Add attributes dict accessor
  • Loading branch information
dangra committed Jun 8, 2018
2 parents 5323b83 + ee042d1 commit c8ff59b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
16 changes: 16 additions & 0 deletions parsel/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ def extract_first(self, default=None):
return default
get = extract_first

@property
def attrib(self):
"""Return the attributes dictionary for the first element.
If the list is empty, return an empty dict.
"""
for x in self:
return x.attrib
else:
return {}


class Selector(object):
"""
Expand Down Expand Up @@ -330,6 +340,12 @@ def remove_namespaces(self):
# remove namespace declarations
etree.cleanup_namespaces(self.root)

@property
def attrib(self):
"""Return the attributes dictionary for underlying element.
"""
return dict(self.root.attrib)

def __bool__(self):
"""
Return ``True`` if there is any real content selected or ``False``
Expand Down
28 changes: 28 additions & 0 deletions tests/test_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,34 @@ def test_simple_selection_with_variables_escape_friendly(self):
lng=lt)],
[u'a'])

def test_accessing_attributes(self):
body = u"""
<html lang="en" version="1.0">
<body>
<ul id="some-list" class="list-cls" class="list-cls">
<li class="item-cls" id="list-item-1">
<li class="item-cls active" id="list-item-2">
<li class="item-cls" id="list-item-3">
</ul>
</body>
</html>
"""
sel = self.sscls(text=body)
self.assertEquals({'lang': 'en', 'version': '1.0'}, sel.attrib)
self.assertEquals({'id': 'some-list', 'class': 'list-cls'}, sel.css('ul')[0].attrib)

# for a SelectorList, bring the attributes of first-element only
self.assertEquals({'id': 'some-list', 'class': 'list-cls'}, sel.css('ul').attrib)
self.assertEquals({'class': 'item-cls', 'id': 'list-item-1'}, sel.css('li').attrib)
self.assertEquals({}, sel.css('body').attrib)
self.assertEquals({}, sel.css('non-existing-element').attrib)

self.assertEquals(
[{'class': 'item-cls', 'id': 'list-item-1'},
{'class': 'item-cls active', 'id': 'list-item-2'},
{'class': 'item-cls', 'id': 'list-item-3'}],
[e.attrib for e in sel.css('li')])

def test_representation_slice(self):
body = u"<p><input name='{}' value='\xa9'/></p>".format(50 * 'b')
sel = self.sscls(text=body)
Expand Down

0 comments on commit c8ff59b

Please sign in to comment.