Поиск функции тайм-аута в Python, которая будет работать в Windows

#python #selenium

#питон #селен

Вопрос:

У меня есть программа на Python в Windows 10, которая запускает цикл тысячи раз с несколькими функциями, которые иногда могут зависать и останавливать выполнение программы. Некоторые из них являются функциями ввода-вывода, а некоторые — функциями selenium webdriver. Я пытаюсь создать механизм, который позволит мне запускать функцию, затем завершать эту функцию через указанное количество секунд и повторять попытку, если эта функция не завершилась. Если функция завершается нормально, пусть выполнение программы продолжается, не дожидаясь окончания тайм-аута.

Я просмотрел по крайней мере дюжину различных решений и не могу найти что-то, что соответствует моим требованиям. Многие требуют СИГНАЛОВ, которые недоступны в Windows. Некоторые порождают процессы или потоки, которые потребляют ресурсы, которые нелегко освободить, что является проблемой, когда я собираюсь запускать эти функции тысячи раз. Некоторые работают для очень простых функций, но терпят неудачу, когда функция вызывает другую функцию.

Ситуации, для которых это должно работать:

  1. Должен запускаться в Windows 10
  2. Команда «driver.get» для selenium webdriver для чтения веб-страницы
  3. Функция, которая считывает или записывает в текстовый файл
  4. Функция, которая выполняет внешнюю команду (например, проверяет мой IP-адрес или подключается к VPN-серверу)

Мне нужно иметь возможность указывать разные тайм-ауты для каждой из этих ситуаций. Запись файла должна занимать <2 секунд, тогда как подключение к VPN-серверу может занять 20 секунд.

Я пробовал следующие библиотеки функций:

  1. timeout-декоратор 0.5.0
  2. wrapt-timeout-декоратор 1.3.1
  3. функция-тайм-аут 4.3.5

Вот урезанная версия моей программы, которая включает функции, которые мне нужно включить в функцию тайм-аута:

 import csv
import time
from datetime import date 
from selenium import webdriver
import urllib.request

cities = []
total_cities = 0
city = ''
city_counter = 0
results = []

temp = ''
temp2 = 'IP address not found'
driver = None
            
if __name__ == '__main__':
    #Read city list
    with open('citylist.csv') as csvfile:
        readCity = csv.reader(csvfile, delimiter='n');
        for row in csvfile:
            city = row.replace('n','')
            cities.append(city.replace('"',''))
    
    #Get my IP address
    try:
        temp = urllib.request.urlopen('http://checkip.dyndns.org')
        temp = str(temp.read())
        found = temp.find(':')
        found2 = temp.find('<',found)
    except:
        pass
        
    if (temp.find('IP Address:') > -1):
        temp2 = temp[found 2:found2]

    print(' IP: [',temp2,']n',sep='')
    
    total_cities = len(cities)
    
    ## Open browser for automation
    try: driver.close()
    except AttributeError: driver = None
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    driver = webdriver.Chrome(options=options)

    #Search for links
    while (city_counter < total_cities):
        city = cities[city_counter]     
        
        searchTerm = 'https://www.bing.com/search?q=skate park '   city

        ## Perform search using designated search term
        driver.get(searchTerm)
        haystack = driver.page_source
                
        driver.get(searchTerm)
            
        found = 0
        found2 = 0
        while (found > -1):
            found = haystack.find('<a href=',found2)
            found2 = haystack.find('"',found 10)
            if (haystack[found 9:found 13] == 'http'):
                results.append(haystack[found 9:found2])
        
        city_counter  = 1
    
    driver.close()
    
    counter = 0
    while counter < len(results):
        print(counter,': ',results[counter],sep='')
        counter  = 1
 

Файл citylist.csv:

 "Oakland, CA",
"San Francisco, CA",
"San Jose, CA"
 

Комментарии:

1. Когда вы говорите о «порождении процессов или потоков, которые потребляют ресурсы, которые не могут быть легко освобождены», вы говорите о накладных расходах на создание и управление потоками? Обычным решением этой проблемы является использование пулов потоков. Платформам нравится . NET, как правило, делает это под капотом с помощью трудоемких функций ввода-вывода, подобных вашей, и func-timeout выглядит приемлемым для такого подхода в Python.