Scraping the Bundesliga table and saving it to CSV
Great answers, as always.
Just a few remarks from me:

There is not enough validation in your project.
You are scraping a website that could change at any time, and your script is expecting DOM elements that may not be there. So you need to check each of them.

From the doc (emphasis is mine):


  If find_all() can’t find anything, it returns an empty list. If find()
  can’t find anything, it returns None


To avoid repetition, instead of repeatedly calling club.find (even if it's just a few times), you could have a for loop, using a list or dictionary containing the DOM elements being sought and the matching HTML attribute. Then you validate the existence of the element and extract the text value in the same pass. Thus, your code becomes more solid and easier to maintain. On the other hand, you have just 5 elements in this code. But your next project may involve retrieving a lot more.

Your HTTP request can fail too, for lots of reasons like lost connectivity. Then the rest of your code will fail. I suggest to wrap the HTTP request in its own try/catch block and stop execution if it fails. There is no point trying to parse the HTML if it was not retrieved.

It is good to have exception handling in the functions that do specific tasks, but the main function should also have its own generic exception handler. Advice: log every exception to a file. Especially if the script is going to run unattended.

One last thing: you should always test your code in less than ideal conditions: try to run it against another, arbitrary  website, or a domain name that does not even exist, and see how it behaves.