0

I am using Python 3.7 and I have a question about some code & an error that just happened.

Basically my code reads like this:

try:
    # Sometimes the <span> tag has a <a> tag as a child element...
    post_company = card.find("span", {"class": "company"}).find("a").decode_contents().replace("\u2026", "...")
except AttributeError:
    # ...And sometimes it doesn't.
    post_company = card.find("span", {"class": "company"}).decode_contents().replace("\u2026", "...")

But I still got this error message:

Traceback (most recent call last):
  File "C:/Users/Roland/dir1/2020/Indeed-Scraper/database/database.py", line 163, in update_post_from_soup
    post_company = card.find("span", {"class": "company"}).find("a").decode_contents().replace("\u2026", "...")
AttributeError: 'NoneType' object has no attribute 'find'

Line 163 mentioned in the trace is the line in the try block. So it raised an AttributeError because there was no <a></a> tag within the <span>. I get that. But why didn't my except block catch this and execute the alternative line? Isn't except AttributeError handling precisely that error msg?

As this link says: "The except clause will only catch exceptions that are raised inside of their corresponding try block". So yeah, it should've caught it, no?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Roly Poly
  • 489
  • 1
  • 9
  • 19
  • 1
    You're not only using ```.find()``` to find 'a'. You're also using it in ```card.find()``` That's the error that it's throwing here. Your card object is here ```None``` which is why it's throwing this error. – Jeroen Mar 01 '20 at 02:14
  • So wait: my except block has ```card.find("span", {"class": "company"}).decode_contents().replace("\u2026", "...")``` which caused the AttributeError (on line 165). But the "Traceback" info still points to line 163? I don't get it. – Roly Poly Mar 01 '20 at 02:31
  • you have duplicate .find calls in 'card.find("span", {"class": "company"}).find("a")' so you can get this error in couple of ways: 1 - card was None, 2 - card.find(..) was None – Hrisimir Dakov Jun 08 '20 at 10:01

1 Answers1

2

It actually catches it, but your 'except' block generates anoter one.

Hrisimir Dakov
  • 557
  • 3
  • 9
  • 1
    the 'card' is None, you need to check why – Hrisimir Dakov Mar 01 '20 at 02:14
  • Ohhh, thats why. I didn't consider that my "card" variable could be None. Thanks guys – Roly Poly Mar 01 '20 at 02:21
  • Please see my comment re: 'But the "Traceback" info still points to line 163? I don't get it.' This is saying the AttributeError happened on line 165 within the ```except``` block, but the trace points to the line prior? Is it just not intelligent enough to follow the program thru the ```except``` block, into the ```except``` block's card.find() and highlight line 165 for me? Reply appreciated, it would teach me some nuance about the stack trace. – Roly Poly Mar 01 '20 at 02:34
  • Without going into details - your code structure is bad. Instead of using single 'post_company' variable, you will be better off using separate 'post_company_tag' for keeping the HTML element, and split the code to multiple rows. Example pseudo-code: 1. pc_tag = card.find(..) | 2. if not pc_tag: raise/continue ... | 3. if pc_tag.a: pc_tag = pc_tag.a | 4. post_company = pc_tag.decode..| Hope this helped. – Hrisimir Dakov Jun 08 '20 at 09:59