Ошибка в скрипте Selenium / Python во время цикла, который содержит «ожидание веб-драйвера до» в Instagram - PullRequest
0 голосов
/ 14 декабря 2018

Я кодирую скрипт, который устанавливает лайки на фотографиях Instagram, но после некоторых лайков (один раз 14, 50, 64) мне выдает ошибка:

in <module> ui.WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dCJp8.afkep.coreSpriteHeartOpen._0mzm-"))).click() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 80, in until raise TimeoutException(message, screen, stacktrace) TimeoutException: Message:

Я понимаю, чтопроблема должна быть в ожидании web-драйвера, но я не знаю, как улучшить мой скрипт.

это мой скрипт:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import ui
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome(executable_path = '/usr/local/bin/chromedriver')
driver.implicitly_wait(30)
driver.get("https://www.instagram.com/accounts/login/?source=auth_switcher")

#log in 
time.sleep(1)
usm = driver.find_element_by_name('username').send_keys("givcomomvrvglino")
pwd = driver.find_element_by_name('password').send_keys("x")
btnLog = driver.find_element_by_tag_name('form').submit()

#disattiva le notifiche
ui.WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".aOOlW.HoLwm"))).click()

tag = "likeforfollow"

url_to_search = "https://www.instagram.com/explore/tags/" + tag + "/"

driver.get(url_to_search)

contatore = 0

for i in range(500):
  if i == 0:
        ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".v1Nh3.kIKUG._bz0w"))).click()
        ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dCJp8.afkep.coreSpriteHeartOpen._0mzm-"))).click()
        ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".HBoOv.coreSpriteRightPaginationArrow"))).click()

  else:
        ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dCJp8.afkep.coreSpriteHeartOpen._0mzm-"))).click()
        ui.WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".HBoOv.coreSpriteRightPaginationArrow"))).click()

  contatore = contatore + 1

  print(contatore)

  time.sleep(3)

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Как вы упомянули оболочка выдает эту ошибку иногда после нескольких лайков (один раз 14, 50, 64) , поэтому практически не существует определенной / конкретной ошибки как таковой.

Если вы посмотрите на Дерево DOM из Instagram :

  • css содержит ссылку на реагироватьroot

    <style type="text/css" data-isostyle-id="786433">#react-root,article,div,footer,header,main,nav,section{-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;border:0 solid #000;-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;margin:0;padding:0;position:relative}</style>
    
  • <body> начинается с тега <span> и содержит реагирующий корень следующим образом:

    <span id="react-root">
    

Так как ваши Стратегии локатора основаны на этих динамических классах, например, v1Nh3, kIKUG, _bz0w, _0mzm- и т. Д., Поиск элементовнеизбежно потерпят неудачу в любое время либо слишком рано, либо чуть позже во время выполнения теста .


Решение

Пропорциональным решением будет использование Определение стратегии на основе сатирических элементов , присутствующих в HTML DOM .

В качестве примера click() для элемента с текстом как Не нетw on Всплывающее уведомление Instagram Вы можете использовать следующее решение:

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(.,'Not Now')]"))).click()

Подробное обсуждение можно найти в Нажмите «Не сейчас» в уведомлениях Instagram спроситьиспользуя Selenium и Python

0 голосов
/ 15 декабря 2018

Сначала об исключении.

Ссылка из Selenium doc.

TimeoutException Выдается, когда команда не завершается в достаточное время.

WebDriverWait по умолчанию вызывает ExpectedCondition каждые 500 миллисекунд, пока он не завершится успешно.Успешное возвращение для типа ExpectedCondition - это логическое возвращаемое значение true или не нулевое возвращаемое значение для всех других типов ExpectedCondition.

Вы используете условие Явные ожидания .Это ожидает условия, которое вы укажете, прежде чем перейти в своем коде.Если драйвер не может найти элемент в указанное время, будет выдано исключение TimeoutException.Вам нужно будет увеличить время ожидания, чтобы учесть элемент, не загруженный в течение указанного периода времени.

Что касается того, как улучшить код, я бы рекомендовал использовать Неявные ожидания потому что, как только эта функция будет вызвана, она будет установлена ​​на весь срок службы объекта webdriver.

Пример того, как его установить

driver.implicitly_wait(30) # 30 seconds to wait. This tells the Webdriver to poll the DOM for a certain amount of time.
driver.get("http://")
my_element = driver.findElement(By.cssSelector(".v1Nh3.kIKUG._bz0w"))).click()

По истечении этого времени будет выдано исключение.Преимущество неявного ожидания перед явным ожиданием состоит в том, что вам не нужно повторять добавленный код, такой как WebDriverWait(driver, 20).until(EC.element_to_be_clickable.Недостаток неявного ожидания состоит в том, что он не учитывает ожидаемые условия, если они необходимы.

Если вам нужно использовать явные ожидания, я бы однажды создал экземпляр Webdriver в блоке try, или это может бытьсделано в скрипте / методе установки.Я не вижу ваш полный сценарий, но в случае, если вы не добавили quit () в конец вашего сценария, вам потребуется.Quit закроет браузер и закроет исполняемый файл Driver, который запущен.Метод Quit () можно вызывать в блоке finally или в методе tearDown.

Обновление: несколько дополнительных точек.Вы используете как неявное, так и явное ожидание, что не рекомендуется, посмотрите дополнительную информацию по этому вопросу , не смешивайте неявное и явное ожидания .Я обновил ваш код, чтобы использовать только явный, но его можно легко изменить, и я бы порекомендовал его.Я также увеличил время ожидания до 30 секунд, просмотр строки 10

ИЛИ

wait = ui.WebDriverWait (драйвер, 30) # waitв течение 30 секунд

Я добавил комментарии, поэтому, пожалуйста, прочитайте.

пример

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import ui
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time

try:  
    driver = webdriver.Chrome(executable_path = '/usr/local/bin/chromedriver')
    #=======================================================================
    # Create a single instance for WebDriverWait. 
    # Defines how long to wait.
    #=======================================================================
    wait = ui.WebDriverWait(driver, 30) # wait for 30 seconds

    driver.get("https://www.instagram.com/accounts/login/?source=auth_switcher")

    #log in 
    time.sleep(1)
    usm = driver.find_element_by_name('username').send_keys("givcomomvrvglino")
    pwd = driver.find_element_by_name('password').send_keys("x")
    btnLog = driver.find_element_by_tag_name('form').submit()

    #disattiva le notifiche
    #=======================================================================
    # A successful return is for ExpectedCondition type is Boolean return true or not 
    # null return value for all other ExpectedCondition types.
    #=======================================================================
    element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".aOOlW.HoLwm"))) 
    element.click() # click on element

    tag = "likeforfollow"
    url_to_search = "https://www.instagram.com/explore/tags/" + tag + "/"
    driver.get(url_to_search)

    contatore = 0
    for i in range(500):
        if i == 0:
            #=======================================================================
            # A successful return is for ExpectedCondition type is Boolean return true or not 
            # null return value for all other ExpectedCondition types.
            #=======================================================================
            element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".v1Nh3.kIKUG._bz0w")))
            element.click() # click on element

            element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dCJp8.afkep.coreSpriteHeartOpen._0mzm-")))
            element.click() # click on element

            element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".HBoOv.coreSpriteRightPaginationArrow")))
            element.click() # click on element
        else:
            element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".dCJp8.afkep.coreSpriteHeartOpen._0mzm-")))
            element.click() # click on element

            element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".HBoOv.coreSpriteRightPaginationArrow")))
            element.click() # click on element    
        contatore = contatore + 1
        print(contatore)
        time.sleep(3)
finally:
    driver.close() # close driver executable and chrome browser.

Наконец, я вижу, что вы используете CSS Selector, чтобы найти все свои элементы.Селекторы CSS и ID - хороший выбор на мой взгляд.Сейчас в Интернете много споров о том, какие селекторы вы всегда должны использовать, так что вы можете просто выполнить поиск, но если вас это интересует, это одно конкретное обсуждение, которое я считаю полезным при выборе селектора.Пожалуйста, укажите ответ переполнения стека. селекторы

...