滚动Selenium Webdriver(Python)

时间:2016-12-25 17:29:48

标签: python selenium selenium-webdriver

先决条件。
您需要Instagram上的帐户才能使用此脚本 设置测试环境:

登录,打开所需列表(正常工作):

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep

driver = webdriver.Chrome(
# driver = webdriver.Firefox(    
# driver = webdriver.PhantomJS(
    service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])

driver.get("https://instagram.com/accounts/login")
username = driver.find_element_by_name("username")
password = driver.find_element_by_name("password")

username1 = 'instagram' # change it!
password1 = 'instagrampassword1' # change it!

username.send_keys(username1)
password.send_keys(password1)

submit_button = driver.find_element_by_css_selector(
    '#react-root > div > article > div > div:nth-child(1) > div > form > span > button')
submit_button.click()

sleep(2)

link = 'https://www.instagram.com/youtube/'
driver.get(link)

driver.implicitly_wait(2)
driver.find_elements_by_class_name("_218yx")[2].click()

滚动错误。 如何解决这个问题?

如何在此页面上正确聚焦和滚动?

我的尝试:

driver.find_element_by_class_name("_cx1ua").send_keys(Keys.NULL) # focus
      #The element has been deleted entirely or
      #The element is no longer attached to the DOM.

driver.find_element_by_class_name("_q44m8").send_keys(Keys.NULL)
# cannot focus element

driver.find_element_by_class_name("_qjr85").send_keys(Keys.NULL) 
# cannot focus element


for i in range(5):
    driver.find_element_by_class_name("_cx1ua").send_keys(Keys.END)

=============================================== ==============
到@Moshisho:

我们需要关注一些元素来激活它 问题是我们需要选择什么元素以及如何关注? 这不是"身体":
类似的东西,但不是这样:

background = driver.find_element_by_css_selector("body")
# background = driver.find_element_by_css_selector("div._2uju6")

for i in range(5):
    background.send_keys(Keys.SPACE)
    time.sleep(1)

没有它,此命令不起作用。

到@Naveen:

print(driver.find_element_by_css_selector("div._a1rcs").location_once_scrolled_into_view) # {'x': 0, 'y': 0}
print(driver.find_element_by_class_name("_cx1ua").location_once_scrolled_into_view) # {'x': 376, 'y': 229}
print(driver.find_element_by_class_name("_q44m8").location_once_scrolled_into_view) # {'x': 376, 'y': 180}
print(driver.find_element_by_class_name("_qjr85").location_once_scrolled_into_view) # {'x': 376, 'y': 180}

下一步是什么?

driver.execute_script("window.scrollTo(0, 3000);") # do not working

https://www.instagram.com/youtube/following/

3 个答案:

答案 0 :(得分:4)

请尝试以下代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.support.ui import Select

driver = webdriver.Chrome(
# driver = webdriver.Firefox(    
# driver = webdriver.PhantomJS(
    service_args=['--ignore-ssl-errors=true', '--ssl-protocol=any'])

driver.maximize_window()

driver.get("https://instagram.com/accounts/login")
username = driver.find_element_by_name("username")
password = driver.find_element_by_name("password")

username1 = 'instagramlogin1'    # change it!
password1 = 'instagrampassword1' # change it!

username.send_keys(username1)
password.send_keys(password1)

submit_button = driver.find_element_by_css_selector(
    '#react-root > div > article > div > div:nth-child(1) > div > form > span > button')
submit_button.click()

sleep(2)

link = 'https://www.instagram.com/youtube/'
driver.get(link)

driver.implicitly_wait(2)
following = driver.find_element_by_xpath("//a[@href='/youtube/following/']/span")
total_following = int(following.text)
print "total no. of users following: ", total_following
# click on 239 following, displays 10 users
following.click()

loaded_following = driver.find_elements_by_xpath("//ul[@class='_539vh _4j13h']/li")
loaded_till_now = len(loaded_following)

while(loaded_till_now<total_following):
    print "following users loaded till now: ", loaded_till_now
    print loaded_following[loaded_till_now-1]
    loaded_following[loaded_till_now-1].location_once_scrolled_into_view
    # driver.execute_script("arguments[0].focus();", loaded_following[loaded_till_now-1])
    driver.find_element_by_tag_name('body').send_keys(Keys.END) # triggers AJAX request to load more users. observed that loading 10 users at a time.
    sleep(1) # tried wihtout sleep but throws StaleElementReferenceException. As it takes time to get the resposne and update the DOM
    loaded_following = driver.find_elements_by_xpath("//ul[@class='_539vh _4j13h']/li")
    loaded_till_now = len(loaded_following)

# All 239 users are loaded. 
driver.quit()

观察到浏览器正在发送AJAX请求以加载更多用户。 scroll using mouse or enter Space or End keys

时会触发此操作

答案 1 :(得分:2)

要在窗口中滚动,您需要执行JavaScript,试试这个:

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

编辑:为了聚焦元素(它需要能够获得焦点,例如锚点,输入,按钮等......)你还需要使用JavaScript执行器:

elementToFocus = driver.find_element_by_id("yourID")
driver.execute_script("arguments[0].focus();", elementToFocus)

答案 2 :(得分:0)

我正在使用动态 React 应用程序,我需要滚动到页面底部以使 React 呈现所有数据。

由于未知原因,基于 JS execute_script 的解决方案不起作用。但是我得到了 send_keys 解决方案:

# scroll to bottom to load all
WebDriverWait(driver, 5).until(
    EC.presence_of_element_located((By.XPATH, "//body"))
)

attempt_num = 2
while attempt_num > 0:
    try:
        elem = driver.find_element_by_xpath("//body")
        elem.click()
        elem.send_keys(Keys.END)
    except StaleElementReferenceException as e:
        print(e)
    attempt_num = attempt_num - 1

主体上的 click() 和 StaleElementReferenceException 的重试至关重要。我还没有找到比重试更优雅的方法。

查看How to avoid "StaleElementReferenceException" in Selenium?的最佳答案