Search code examples
python-2.7powershelllambdaweb-scrapingattributeerror

Python. AttributeError: 'NoneType' object has no attribute 'startswith'


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'

Solution

  • 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