I will start out by saying I'm not endorsing scraping of sites that do not allow it in their terms of service and this is purely for academic research of hypothetical gathering of financial data from various websites.
If one wanted to look at this link:
https://finviz.com/screener.ashx?v=141&f=geo_usa,ind_stocksonly,sh_avgvol_o100,sh_price_o1&o=ticker
...which is stored in a URLs.csv file, and wanted to scrape columns 2-5 (ie. Ticker, Perf Week, Perf Month, Perf Quarter) and wanted to export that to a CSV file, what might the code look like?
Trying to use another user's answer from a past question I had, so far I have something that looks like this:
from bs4 import BeautifulSoup
import requests
import csv, random, time
# Open 'URLs.csv' to read list of URLs in the list
with open('URLs.csv', newline='') as f_urls, open('Results.csv', 'w', newline='') as f_output:
csv_urls = csv.reader(f_urls)
csv_output = csv.writer(f_output, delimiter=',')
headers = requests.utils.default_headers()
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
csv_output.writerow(['Ticker', 'Perf Week', 'Perf Month', 'Perf Quarter'])
# Start to read the first URL in the .csv and loop for each URL/row in the .csv
for line in csv_urls:
# Start at first url and look for items
page = requests.get(line[0])
soup = BeautifulSoup(page.text, 'html.parser')
symbol = soup.findAll('a', {'class':'screener-link-primary'})
perfdata = soup.findAll('a', {'class':'screener-link'})
lines = list(zip(perfdata, symbol))
# pair up every two teams
for perfdata1, symbol1 in zip(lines[1::2], lines[::2]):
# extract string items
a1, a2, a3, _ = (x.text for x in symbol1 + perfdata1)
# reorder and write row
row = a1, a2, a3
print(row)
csv_output.writerow(row)
...I get the following output:
('1', 'A', '7.52%')
('-0.94%', 'AABA', '5.56%')
('10.92%', 'AAL', '-0.58%')
('4.33%', 'AAOI', '2.32%')
('2.96%', 'AAP', '1.80')
('2.83M', 'AAT', '0.43')
('70.38', 'AAXN', '0.69%')
...
So it's skipping some rows and not returning the data in the right order. I would like to see in my final output:
('A', '7.52%', -0.94%, 5.56%)
('AA', '0.74%', 0.42%, -20.83%)
('AABA', '7.08%', '0.50%', '7.65%')
('AAC', '31.18%', '-10.95%', '-65.14%')
...
I know it's the last sections of the code that are incorrect but looking for some guidance. Thanks!