WebDriverWait
- не что иное, как (вполне) причудливый цикл while / catch / sleep ; в вашем конкретном случае вы можете захотеть скопировать его самостоятельно по одной простой причине - он опрашивает каждые 500 мс, что, вероятно, является слишком подробным разрешением для этой задачи. Это также защищает вас от более детального контроля.
Вот как сделать логику самостоятельно - есть логическая переменная - пользователь онлайн или нет; в зависимости от значения, check - видимый элемент (.is_displayed()
), время ожидания X и повтор. Исключение NoSuchElementException
, StaleElementReferenceException
будет учитываться как пользователь в автономном режиме / логическое значение false.
В конце ваш код будет очень близок к логике в WebDriverWait
- все же ваш и более гибкий, если это необходимо.
Либо просто передайте больший внутренний опрос в WebDriverWait
в текущем коде - это аргумент poll_frequency
вызова:)
WebDriverWait(driver, 28800, 5) # the value is in seconds
Я не могу знать, где и что вы прочитали, это плохая практика использовать WebDriverWait с большим количеством секунд; как видно из кода, сколько времени дается запуску метода.
Я полагаю, что совет был в тонусе: «Это плохая практика - использовать WebDriverWait с большим количеством секунд, , потому что если условие не будет выполнено в течение X секунд, оно никогда не будет выполнено, и ваш код будет просто вращаться и вращаться.". Что на самом деле для вас желаемое поведение:)
Я бы тоже не стал беспокоиться о налогах на процессор - эти проверки очень легкие, ничего страшного. Для этой большой среды выполнения меня беспокоит утечка памяти в самом браузере;)
Что касается оптимизации кода - то, что я хотел бы сделать, это сократить повторения операторов; с обратной стороной снижения его читабельности немного. Мое мнение о петле:
user_online = False
while True:
# we'll be checking for the reverse of the last status of the user
check_method = EC.visibility_of_element_located if not user_online else EC.invisibility_of_element_located
# in the conversation page, a span with title online is diplayed when user is online.
# the web driver will wait 8hrs=28800s for the user status to change all
# the script will be killed by webdriverWait if that doesn't happen
element = WebDriverWait(driver, 28800, 5).until(
check_method((By.XPATH, "//span[@title = 'online']")))
# The moment the user changed status
now = datetime.datetime.now().strftime("%H:%M:%S")
print("{} at : {}".format('online' if not user_online else 'offline', now)) # if you're using python v3.6 or more, the fstrings are much more convenient for this
print("************")
user_online = not user_online # switch, to wait for the other status in the next cycle
И наконец, по коду - скрипт нельзя оставлять «бесконечным». Зачем? Потому что, если пользователь не изменит статус в течение 8 часов, WebDriverWait
остановится. Чтобы спасти это, оберните тело цикла в try / кроме:
from selenium.common.exceptions import TimeoutException # put this in the beginning of the file
while True:
try:
# the code from above
except TimeoutException:
# the status did not change, repeat the cycle
pass
Запись в файл
Возможно, вы захотите прочитать a бит как сделать это - это довольно простая операция.
Вот пример - откройте файл для добавления (чтобы там сохранялись предыдущие журналы), обернув цикл while
:
with open("usermonitor.log", "a") as myfile:
while True:
# the other code is not repaeted for brevity
# ...
output = "{} at : {}".format('online' if not user_online else 'offline', now)
print(output)
myfile.write(output + "\n") # this will write (append as the last line) the same text in the file
# write() does not append newlines by itself - you have to do it yourself