0

I'm trying to write a basic python program that takes the price to book ratio from yahoo finance's website. However, i'm getting an error:

failed in the main loop a bytes-like object is required, not 'str'

I've tried using encoding with this line:

sourceCode.read().decode('utf-8')

However this leads to another error of:

failed in the main loop 'bytes' object has no attribute 'read'

Any Help would be appreciated. The full code is below:

import time
    import urllib.request
    from urllib.request import urlopen

stocks = ['aapl', 'fb', 'goog']

def keyStats(stock):
  try:
      sourceCode = urllib.request.urlopen('https://finance.yahoo.com/quote/' + stock + '/key-statistics?p=' + stock).read()
      ptb = sourceCode.split('Price/Book</span><!-- react-text: 58 --> <!-- /react-text --><!-- react-text: 59 -->(mrq)<!-- /react-text --><sup aria-label="KS_HELP_SUP_undefined" data-reactid="60"></sup></td><td class="Fz(s) Fw(500) Ta(end)" data-reactid="61">')[1].split('</td>')[0]
      print ('Price to Book Ratio: ', stock, ptb)

  except (Exception) as e:
      print ('failed in the main loop', e)

for newStock in stocks:
  keyStats(newStock)
  time.sleep(1)
bkrause404
  • 35
  • 1
  • 8
  • Try `ptb = ptb.decode("utf-8")` – L3viathan Aug 05 '18 at 17:07
  • When using this I still get: failed in the main loop a bytes-like object is required, not 'str' – bkrause404 Aug 05 '18 at 17:09
  • 2
    You're saying that "urllib is not as easy to use as it could be". So use requests instead: https://pypi.org/project/requests/ . Also, at some point instead of `split()` you'll find it easier to use Beautiful Soup: https://www.crummy.com/software/BeautifulSoup/bs4/doc/ – J_H Aug 05 '18 at 17:16

1 Answers1

0

urlopen returns a response object that, when read using read(), returns a bytes object. This is because there’s generally no guarantee about whether a HTTP request returns a binary response or some response that can be properly decoded into a string.

Instead, it is up to you to decode the response explicitly, for example if you know exactly that there is a response in UTF-8, or by explicitly checking the Content-Type header in the HTTP response.

So you need to do it like this:

sourceCode = urllib.request.urlopen(url).read().decode()

That attempts to decode the bytes response into a string using UTF-8 (by default). And then sourceCode will be a string which you will be able to call str.split() on.

poke
  • 369,085
  • 72
  • 557
  • 602