#python #amazon-web-services #selenium #aws-lambda
#python #amazon-веб-сервисы #selenium #aws-lambda
Вопрос:
Я создал webscraper, используя python и selenium с помощью geckodriver, в настоящее время он запущен в экземпляре EC2 по расписанию crontab.
Моя проблема в том, что для завершения загрузки требуется более 5 минут, и я хочу использовать функции lamda для запуска моего scraper, но они позволяют выполнять только 5 минут.
Итак, у меня есть код, похожий на этот.
from selenium import webdriver
def start_browser(url):
browser = webdriver.Firefox( executable_path="./geckodriver")
executable_path="./geckodriver")
browser.get(url)
return browser
def log_in(user, pass, user_elem, pass_elem, login_elem, browser):
user_elem.click().send_keys(user)
pass_elem.click().send_keys(pass)
login_elem.click()
return browser
def nav_to_data(browser, data_elem)
data_elem.click()
return browser
def find_data(browser, data_table)
data_links = data_table.find_elements_by_tag_name("tr")
return data_links, browser
Я думаю, что эти функции можно было бы запускать на лямбда-функциях, передавая экземпляры браузера / webdriver друг другу?
Часть, с которой я борюсь, заключается в циклическом просмотре данных и ожидании завершения всех загрузок, это займет больше времени, чем 5 минут.
Есть ли какие-нибудь обходные пути для этого?
def download_data(browser, link)
link.click()
time.sleep(2)
download_elem = browser.find_element_by_id("download_xls_file")
download_path = download_elem.click()
return download_path
# THIS TAKES LONGER THAN 5 mins
download_paths = []
for link in data_links:
download = download_data(browser, link) # clicks a link to a new page wdownload button and returns path to the .xls file
download_paths.append(download)
upload_data()
Комментарии:
1. Лямбда-функции поддерживали ограничение по времени в 15 минут в течение нескольких месяцев, FWIW.
2. вау, я понятия не имел, спасибо!
Ответ №1:
Вы можете разделить свои данные и использовать рекурсивный лямбда-код для обработки фрагментов вашего списка. Беру пример из моего блога
def invoke_self_async(data_list, context):
this_data_list = data_list[0:20] # increase number as needed
new_event = {
'data': data_list[20:] # needs to match above number
}
boto3.client('lambda').invoke_async(
FunctionName=context.invoked_function_arn,
InvokeArgs=json.dumps(new_event)
)
my_data = []
for data in data_list:
download = download_data(browser, data) # returns path to .xls file
my_data.append(download)
return my_data
Комментарии:
1. Ах, моя ошибка, что я не сделал это настолько ясным в своем посте, данные в data_list на самом деле являются ссылками для загрузки файлов .xls с моими данными, а не необработанными данными
2. Точно, если загрузка
n
ссылок занимает у вас более 5 минут, вы можете создатьn/x
разделы и загрузить каждый из них в своем собственном лямбда-исполнении,invoke_async
гарантируя, что ваши лямбды не будут ждать завершения друг друга, поэтому процесс будет отчасти параллельным.3. ах, я понимаю, что вы имеете в виду, я попробую реализовать это, большое спасибо, это здорово!