0

For a newbie exercise , I am trying to find the meta tag in a html file and extract the generator so I did like this :

Version = soup.find("meta", {"name":"generator"})['content']

and since I had this error :

TypeError: 'NoneType' object has no attribute '__getitem__'

I was thinking that working with exception would correct it, so I wrote :

try: Version = soup.find("meta", {"name":"generator"})['content']

except NameError,TypeError:

     print "Not found"

and what I got is the same error.

What should I do then ?

2
  • 3
    It sounds like soup.find() is returning None. According to the docs, that means it found nothing. Commented Nov 7, 2013 at 15:45
  • in some cases that metatag doesn't exist, and that's why I would like to test it, if it exists, I print it if not I print another message. Commented Nov 7, 2013 at 15:46

2 Answers 2

7

The soup.find() method did not find a matching tag, and returned None.

The [...] item access syntax looks for a __getitem__ method, which is the source of the AttributeError here:

>>> None[1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'

Test for None explicitly:

Version = soup.find("meta", {"name":"generator"})
if Version is not None:
    Version = Version['content']
else:
    print "Not found"

Your exception handling would work too, provided you use parenthesis to group the exceptions:

try:
    Version = soup.find("meta", {"name":"generator"})['content']
except (NameError, TypeError):
    print "Not found"

Without parenthesis you are telling Python to catch NameError exceptions and assign the resulting exception object to the local name TypeError. This except Exception, name: syntax has been deprecated because it can lead to exactly your situation, where you think you are catching two exceptions.

However, your code here should not throw a NameError exception; that'd be a separate problem better solved by instantiating your variables properly; the following would work just as well here:

try:
    Version = soup.find("meta", {"name":"generator"})['content']
except TypeError:
    # No such meta tag found.
    print "Not found"
Sign up to request clarification or add additional context in comments.

1 Comment

To expand further, what you're doing with except NameError, TypeError is catching NameError and assigning the caught exception to the name TypeError. Since the code doesn't throw NameError, this except will never catch anything.
4

Try this:

content = None
Version = soup.find("meta", {"name":"generator"})
if Version:
    content = Version.get('content') 
    #or even
    #Version = Version.get('content')
else:
    print "Not found"

The issue is, soup.find returns a None if match was not found, and extracting data out of None results in error.

2 Comments

Thanks it works. So there is no way to make the code shorter and avoid using two variables (Version and content) ?
Why would you want to do that? This is readable, and simple.. But if you do insist, you can just do Version = Version.get('content')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.