Вопрос Python 3 о переборе массива с использованием CSV-файла с Selenium и Concurrent Futures

Нуб Python здесь, поэтому я постараюсь предоставить как можно больше подробностей. Я экспериментирую с модулем параллельных фьючерсов Python, чтобы посмотреть, смогу ли я ускорить парсинг с помощью Selenium. Я соберу некоторые финансовые данные с сайта, используя следующие URL-адреса в CSV-файле под названием inputURLS.csv. Мы сократим список акций и будем иметь одну фальшивую акцию на случай исключения. Фактический URL-адрес csv длиннее, поэтому я хотел бы попытаться извлечь из csv, а не вводить массив в моем скрипте Python.

https://www.benzinga.com/quote/TSLA
https://www.benzinga.com/quote/AAPL
https://www.benzinga.com/quote/XXXX
https://www.benzinga.com/quote/SNAP

Вот мой код Python для извлечения 3 элементов данных — количество акций, рыночная капитализация и коэффициент PE. Сценарий отлично работает вне параллельных фьючерсов.

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import csv
import concurrent.futures
from random import randint
from time import sleep

options = webdriver.ChromeOptions()
#options.add_argument("--headless") #optional headless
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ['enable-automation'])
options.add_argument("--disable-extensions")
driver = webdriver.Chrome(options=options, executable_path=r'D:\SeleniumDrivers\Chrome\chromedriver.exe')
driver.execute_cdp_cmd('Network.setUserAgentOverride',{"userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'})

OutputFile = open('CSVoutput.csv', 'a')
urlList = []

with open('inputURLS.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        urlList.append(row[0])
    print (urlList) #make array visible in viewer

def extract(theURLS):
    for i in urlList:
        driver.get(i)
        sleep(randint(3, 10)) # random pause
        try:
            bz_shares = driver.find_element_by_css_selector('div.flex:nth-child(10) > div:nth-child(2)').text #get shares number
            print(bz_shares) # to see in viewer
            OutputFile.write(bz_shares) # save number to csv output
        except NoSuchElementException:
            print("N/A") # print N/A if stock does not exist
            OutputFile.write("N/A") # save non value to csv output
        try:
            bz_MktCap = driver.find_element_by_css_selector('div.flex:nth-child(5) > div:nth-child(2)').text #get market cap
            print(bz_MktCap) # to see in viewer
            OutputFile.write("," + bz_MktCap) # save market cap to csv output
        except NoSuchElementException:
            print("N/A") # print N/A if no value
            OutputFile.write(",N/A") # save non value to csv output
        try:
            bz_PE = driver.find_element_by_css_selector('div.flex:nth-child(8) > div:nth-child(2)').text #get PE ratio
            print(bz_PE) # to see in viewer
            OutputFile.write("," + bz_PE) # save PE ratio to csv output
        except NoSuchElementException:
            print("N/A") # print N/A if no value
            OutputFile.write(",N/A") # save non value to csv output
        print(driver.current_url) # see URL screen in viewer
        OutputFile.write("," + driver.current_url + "\n") # save URL to csv output

        return theURLS

with concurrent.futures.ThreadPoolExecutor() as executor:
    executor.map(extract, urlList)

Когда я запускаю скрипт, я получаю следующие результаты в свой выходной файл:

963.3M,602.9B,624.6,https://www.benzinga.com/quote/TSLA
963.3M,602.9B,624.6,https://www.benzinga.com/quote/TSLA
963.3M,602.9B,624.6,https://www.benzinga.com/quote/TSLA
963.3M,602.9B,624.6,https://www.benzinga.com/quote/TSLA

Итак, скрипт перебирает мой CSV-файл, но застревает в первой строке. Я возвращаю 4 строки данных — это количество URL-адресов, с которых я начинаю, — но я получаю данные только для первого URL-адреса. Если бы у меня было 8 URL-адресов, то же самое происходит 8 раз и т. д. Я не думаю, что правильно перебираю массив URLlist в своей функции. Был бы признателен за любую помощь, чтобы исправить это. Я собрал это вместе с различными сайтами и видео на YouTube, которые я смотрел на параллельных фьючерсах, но я полностью застрял. Спасибо большое!


person RTaylor    schedule 28.05.2021    source источник
comment
Ваш extract() должен быть методом, применяемым к каждому элементу в urlList, а не принимать сам список.   -  person JonSG    schedule 28.05.2021
comment
Вам также понадобится threading.Lock() при написании. см.: stackoverflow.com/questions/33107019/   -  person JonSG    schedule 28.05.2021
comment
в любом случае вам понадобится отдельный драйвер/браузер для каждого потока. Например, вы можете разбить свой список на 4 части и запускать их одновременно, используя новый экземпляр веб-драйвера для каждой.   -  person pcalkins    schedule 28.05.2021