0

So Im trying to have this script run multiple variables from the ticker variable

Example ticker = ['NFLX','APPL']

How would I be able to loop this script so that I can run it on more than one variable

import requests
from bs4 import BeautifulSoup

ticker = 'NFLX'

url = 'https://finance.yahoo.com/quote/' + ticker

r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')

name = soup.find('div', {'class':'Mt(15px)'}).find_all('h1')[0].text
price = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[0].text
change = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[1].text
cap = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[0].text
capnumber = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[1].text
topnews = soup.find('h3', {'class':'Mb(5px)'}).find_all('a')[0].text

print(name)
print ('https://finance.yahoo.com/quote/' + ticker)
print("Last Price:",price)
print("Change:", change)
print(cap,":", capnumber)
print("Top News:", topnews)

The current script returns

Netflix, Inc. (NFLX)
https://finance.yahoo.com/quote/NFLX
Last Price: 658.29
Change: +4.23 (+0.65%)
Market Cap : 291.591B
Top News: Russia investigates Netflix after complaint over LGBT content

I would like it to still return the same layout but then spaced between each result or separated by a dash line

Im super new to coding, so Im sure this is a very cumbersome path to get the desired result, so if someone can provide suggestions too to make it neater that would be appreciated as well.

gambo
  • 3
  • 4
  • Welcome to SO! You can just wrap all of the logic in a for loop: `for ticker in tickers` with `tickers = ['NFLX','APPL']` – joshmeranda Nov 26 '21 at 02:36
  • I'm confused by what you want. The question title does not seem to be what you need. Printing dashes is super simple which is what is sounds like you want with `would like it to still return the same layout but then spaced between each result or separated by a dash line` – ViaTech Nov 26 '21 at 02:42
  • You might also be interested in a library called `yfinance` which does most of what you want. – wombat Nov 26 '21 at 02:42
  • @wombat Thanks for the suggestion! I know there are a lot of ways to find the info Im looking for (I have a stock bot actually in my discord), but I wanted to learn some stuff relating to what Im interested in. Ill take a look at that for future reference though! – gambo Nov 26 '21 at 04:48
  • @ViaTech Sorry if the title is confusing. Basically wanted to be able to run the script I wrote with more than one variable. This way I can check on x tickers at once rather than having to go back through and change and run each time. If. you see the solution, youll see what Im looking for. – gambo Nov 26 '21 at 04:49
  • @joshmeranda Thanks josh! Im still super new to coding, so needed it more broken out, but thanks for the help! – gambo Nov 26 '21 at 04:50

2 Answers2

1

I'd approach it this way, first you need to define a function that holds the scraping process then we pass the ticker in a variable called x. New function would be called scrape(x)

Next, list all tickers in an array and use python's for command to loop through the function for each ticker in our array list. See modified code below.

import requests
from bs4 import BeautifulSoup

def scrape(x):
    ticker = x

    url = 'https://finance.yahoo.com/quote/' + ticker

    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'html.parser')

    name = soup.find('div', {'class':'Mt(15px)'}).find_all('h1')[0].text
    price = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[0].text
    change = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[1].text
    cap = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[0].text
    capnumber = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[1].text
    topnews = soup.find('h3', {'class':'Mb(5px)'}).find_all('a')[0].text

    print(name)
    print ('https://finance.yahoo.com/quote/' + ticker)
    print("Last Price:",price)
    print("Change:", change)
    print(cap,":", capnumber)
    print("Top News:", topnews)
    print("\n")

tickerArray = ["NFLX", "MRK", "ADSK"]
for x in tickerArray:
    scrape(x)
0

You can put everything into a method, then pass a parameter 'ticker' into it, one variable in the list at a time. Alternatively you can pass the whole list in and do the for loop inside the method.

import requests
from bs4 import BeautifulSoup
#given input
tickers = ['NFLX','APPL']

def urlDisplay(ticker):
    url = 'https://finance.yahoo.com/quote/' + ticker

    r = requests.get(url)
    soup = BeautifulSoup(r.text, 'html.parser')

    name = soup.find('div', {'class':'Mt(15px)'}).find_all('h1')[0].text
    price = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[0].text
    change = soup.find('div', {'class':'D(ib) Mend(20px)'}).find_all('span')[1].text
    cap = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[0].text
    capnumber = soup.find('div', {'class':'D(ib) W(1/2) Bxz(bb) Pstart(12px) Va(t) ie-7_D(i) ie-7_Pos(a) smartphone_D(b) smartphone_W(100%) smartphone_Pstart(0px) smartphone_BdB smartphone_Bdc($seperatorColor)'}).find_all('span')[1].text
    topnews = soup.find('h3', {'class':'Mb(5px)'}).find_all('a')[0].text

    print(name)
    #print('https://finance.yahoo.com/quote/' + ticker)
    #can just print url variable straight away since you declared it already above.
    print(url)
    print("Last Price:",price)
    print("Change:", change)
    print(cap,":", capnumber)
    print("Top News:", topnews)
#driver code
def main():
    for i in tickers:
        urlDisplay(i)
        print('-' * 20)
if __name__ == "__main__":
    main()
Jyles Jin
  • 16
  • 2
  • 1
    had to clear line 33 with the apostrophes, assuming that was to close the code format when commenting. In `for i in ticker:`, should've been `tickers` to match with updated definition. Can you describe, or link me, what the bottom piece says? the pieces I don't get are the `def main():`, and then anything under `for i in ticker:`. Thanks for the help Jyles! This was really good. – gambo Nov 26 '21 at 03:45
  • @gambo - You're welcome! Glad that it was of help. Sorry I forgot to close the code block properly at the end, new to this. It's fixed now, thanks! Also that typo for `ticker`, yeah that was my bad. The bottom piece `main()` is just to execute the code itself, primarily it's useful for testing, but if your code runs fine without it then you're free to omit it. More about `if __name__ == "__main__"` here: https://stackoverflow.com/questions/419163/what-does-if-name-main-do – Jyles Jin Nov 26 '21 at 05:35
  • @gambo - `for i in tickers` basically means `i` will take on each value in the list `tickers` above for every loop that it runs. So `i = "NFLX"`, `i = "APPL"`... And so on. Then it feeds that variable as a parameter into `urlDisplay()`, giving you the print that you want, then prints a line separator of 20 "-" hyphens long before beginning the next iteration. As given in the other answer by Peter above, you can swap `i` out for any other variable name you want (that isn't already taken or is a reserved keyword) and it will work absolutely fine. – Jyles Jin Nov 26 '21 at 05:56