AttributeError: 'NoneType' object has no attribute 'find' (Cryptocurrency Web Scraper)

Viewed 363

Working on a cryptocurrency widget that scrapes html for specific cryptocurrency prices in real time but ran across AttributeError: 'NoneType' object has no attribute 'find'.

This issue happened all of a sudden and am really confused as to why it didn't show up much sooner. I've run the code many times before this moment with absolutely no issues. So my two questions are...

Why did this happen all of a sudden?

and

How do I fix this?

from tkinter import *
import requests
from bs4 import BeautifulSoup
from tkinter.ttk import *
from time import strftime


def get_crypto_price(coin):
    url = "https://www.google.com/search?q=" + coin + "+price"  # Defining link to coin
    HTML = requests.get(url)  # Requesting link access
    soup = BeautifulSoup(HTML.text, 'html.parser')  # Parser
    text = soup.find("div", attrs={'class': 'BNeawe iBp4i AP7Wnd'}).find("div",
                                                                         attrs={
                                                                             'class': 'BNeawe iBp4i AP7Wnd'}).text  # HTML Scrubber
    return coin + ': ' + text + '  |  '


root = Tk()
root.title('Crypto Widget 2021')
root.geometry('1080x40')
lab = Label(root)
lab.pack()


def update():
    lab['text'] = get_crypto_price("Bitcoin") + get_crypto_price("Ethereum") + get_crypto_price(
        "Litecoin") + get_crypto_price("Dogecoin")
    lab.after(5000, update)


update()


def time():
    string = strftime('%H:%M %p')
    lbl.config(text=string)
    lbl.after(5000, time)


lbl = Label(root, font=('times new roman', 10, 'bold'),
            background='white',
            foreground='black')
lbl.pack(anchor='n')
time()
root.mainloop()
2 Answers

Given the classes you're using in your find function (BNeawe iBp4i AP7Wnd), I'm assuming they are using compiled scoped classes. So if they released a new version of the website, it's possible that the CSS classes for your elements have changed.

Have you been on that website lately and checked the DOM (using the console) to see if those elements still exists?

Looks like your error is coming from line 12, where you have accidentally doubled some code...

I run it but don't get the error you're seeing. But, in general, you're ganging a find on top of another find, and you can avoid errors but breaking it up into stages, instead of just assuming that the first find will always succeed.

So, roughly, instead of saying:

text = soup.find(blah blah blah).find(blah blah blah).text

break it up into stages:

text1 = soup.find(blah blah blah)
if text1:
    text2 = text1.find(blah blah blah...)

and so on.

Or, you can just put everything into a try-except block, but I prefer breaking things down to see where the first failure occurs...

Related