BS4 возвращает AttributeError: объект «NoneType» иногда не имеет атрибута «текст», как решить эту проблему?

Я написал статью, в которой пытается получить данные из Yahoo Finance. Однако первая попытка не удалась где-то в самом начале после того, как удалось получить данные о запасах (цена и изменение цены). Это дало ошибку NoneType. Затем я запустил его снова, и он действительно смог внезапно получить эти данные и продолжил извлекать больше, но где-то на полпути потерпел неудачу с той же ошибкой. Мне это кажется странным, поскольку этот текст атрибута присутствует в html. Тем более странно, что он находит его со второй попытки без настроек. Кроме того, все это находится на одной странице, поэтому мне не нужно ждать некоторых. Это ошибка:

price = soup_ticker.find ('span', class _ = 'Trsdu (0.3s) Fw (b) Fz (36px) Mb (-4px) D (ib)'). text AttributeError: объект 'NoneType' не имеет атрибута 'text '

Это конкретный html:

<span class="Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)" data-reactid="32">22.12</span>

Это мой Кодекс. Имейте в виду, что я новичок, и это все в образовательных целях. Я знаю, что, вероятно, есть миллион способов сделать что-то лучше, чем я сделал ниже, чтобы добиться того же. Заранее благодарим вас за помощь и за ваши знания!

from django.core.management.base import BaseCommand
from urllib.request import urlopen
from bs4 import BeautifulSoup
import json
from scraping.models import StockData

import re


class Command(BaseCommand):
    help = "Collects a stock ticker, price, price change and date"

    # define logic of command
    def handle(self, *args, **options):
        # collect html
        html = urlopen('http://eoddata.com/stocklist/NASDAQ/A.htm')

        regex = re.compile("Display Quote & Chart for")
        regex_price = re.compile("Trsdu(0.3s) Fw(500) Pstart(10px)")
        soup = BeautifulSoup(html, 'html.parser')
        # grab all postings
        td = soup.find_all("td")
        for tag in td:
            for anchor in tag.find_all('a', {'title': regex}):
                ticker = anchor.text
                html_ticker = urlopen("https://finance.yahoo.com/quote/" + ticker + "/")
                soup_ticker = BeautifulSoup(html_ticker, 'html.parser')
                price = soup_ticker.find('span', class_='Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)').text
                change = soup_ticker.find('div', class_="D(ib) Mend(20px)").find_all('span')[1].text

                try:
                    # save in db
                    StockData.objects.create(
                        ticker=ticker,
                        price=price,
                        change=change,
                    )
                    print('%s added' % (ticker,))
                except:
                    print('%s already exists' % (ticker,))
            self.stdout.write('job complete')

person mido_sama    schedule 19.09.2020    source источник
comment
вместо этого вы можете использовать строку, это должно решить вашу проблему.   -  person SerioUs    schedule 20.09.2020


Ответы (1)


Да, вы должны использовать .string в этом Разница между .string и .text BeautifulSoup объясняет разницу между .text и .string. Невозможно использовать .text в версиях bs4 ›4.8.0.

person Sebastian Peterlin    schedule 19.09.2020
comment
Спасибо за комментарий, я пробовал это, но в итоге получил ту же ошибку. price = soup_ticker.find('span', class_='Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)').string AttributeError: 'NoneType' object has no attribute 'string' , но до того, как эта ошибка появится, он говорит следующее: некоторые символы не могут быть декодированы и были заменены символом REPLACEMENT CHARACTER. Это может тебе что-то сказать? Я также буду проверять stackoverflow, чтобы увидеть, есть ли какие-то подсказки относительно этого заменяющего символа. - person mido_sama; 21.09.2020