【问题标题】:Scroll in Selenium Webdriver (Python)在 Selenium Webdriver (Python) 中滚动
【发布时间】:2016-12-25 17:29:48
【问题描述】:

先决条件。
您需要 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

【问题讨论】:

  • 您的问题应该作为题外话结束。提供一些详细信息和描述以使您的问题更清楚......不是每个人都有Instagram 的帐户:)
  • 即使不使用Android/iOs也可以注册。
  • 网页版就够了。
  • 您的尝试是为了聚焦或滚动特定元素?
  • 是的,我想滚动所有关注者列表,每次访问查看 > 10 个关注者。

标签: python selenium selenium-webdriver


【解决方案1】:

试试下面的代码:

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时触发

【讨论】:

  • 谢谢,有趣的属性,但是我如何使用它来做需要的事情呢?请参阅上面向您解释的消息。
  • 我不确定你在说哪个元素(类名是动态的,所以不适合我)。你能分享屏幕截图,突出显示元素以及你想用它做什么吗?单击或发送密钥?
  • 在这种情况下,类名是静态的,只是看起来像动态的。您可以使用不同的浏览器查看。
  • 没有任何操作 self.driver.find_elements_by_class_name("_6jvgy") 我只会得到 10 个元素,
  • 但我想向下滚动,最好是到列表的末尾,以获得 239 个元素(用于 youtube)。
【解决方案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)

【讨论】:

  • 谢谢,我之前在几个地方看到过这段代码sn-p。我们需要关注一些元素来激活它。问题是我们需要选择关注哪些元素以及如何关注?这不是“正文”: background = browser.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) 没有它,这个命令不起作用。
  • 没有任何带有id的元素。
    我已经测试了第二行,但它还不起作用。
    所以我已经按类选择了,但可能需要选择类的第 2 或第 3 个元素
    (我知道怎么做,但是有很多元素,看起来大多数应该是可见的和可以接受的)。
【解决方案3】:

我正在使用动态 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

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

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

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2014-11-29
    • 1970-01-01
    • 2014-11-10
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    相关资源
    最近更新 更多