Why is it this code won't work and give AttributeError?
internship = parser.find_all('a', attrs = {'title': lambda job: job.startswith('Internship')})
while this one works:
internship = parser.find_all('a', attrs = {'title': lambda job: job and job.startswith('Internship')})
This is the error that I got from the first code:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\bs4\element.py", line 1299, in find_all
return self._find_all(name, attrs, text, limit, generator, **kwargs)
File "C:\Python27\lib\site-packages\bs4\element.py", line 549, in _find_all
found = strainer.search(i)
File "C:\Python27\lib\site-packages\bs4\element.py", line 1690, in search
found = self.search_tag(markup)
File "C:\Python27\lib\site-packages\bs4\element.py", line 1662, in search_tag
if not self._matches(attr_value, match_against):
File "C:\Python27\lib\site-packages\bs4\element.py", line 1722, in _matches
return match_against(markup)
File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'startswith'
In the first line of code, you are getting the attribute error because the code assumes that job
contains a string, which has the method startswith()
, but it doesn't contain a string, it contains None
.
In the second line of code, you are not getting the attribute error because the code is testing to see if job
contains None
, before calling startswith()
on it. Another (not quite equivalent but arguably better) way to express
lambda job: job and job.startswith('Internship')
is
lambda job: job.startswith('Internship') if job else False