【问题标题】:Issue Crawling Amazon, Element Cannot Be Scrolled into View问题抓取亚马逊,元素无法滚动到视图中
【发布时间】:2019-02-20 17:38:02
【问题描述】:

我在亚马逊上抓取页面时遇到问题。

我尝试过使用:

  • 执行 JS 脚本
  • 动作链
  • 显式等待

似乎没有任何效果。一切都会引发一个异常或错误。

基础脚本

ff = create_webdriver_instance()
ff.get('https://www.amazon.ca/gp/goldbox/ref=gbps_ftr_s-3_4bc8_dct_10-?gb_f_c2xvdC0z=sortOrder:BY_SCORE,discountRanges:10-25%252C25-50%252C50-70%252C70-&pf_rd_p=f5836aee-0969-4c39-9720-4f0cacf64bc8&pf_rd_s=slot-3&pf_rd_t=701&pf_rd_i=gb_main&pf_rd_m=A3DWYIK6Y9EEQB&pf_rd_r=CQ7KBNXT36G95190QJB1&ie=UTF8')
next_button = ff.find_element_by_xpath('(//li/a[contains(text(), "Next")])[1]')

尝试 #1:执行 JS

脚本

ff.execute_script('arguments[0].scrollIntoView()', next_button)

错误

Element could not be scrolled into view

尝试 #2:动作链

脚本

actions = ActionChains(ff)
actions.move_to_element(next_button)
actions.click(next_button)
actions.perform()

错误

TypeError: rect is undefined

尝试 #3:显式等待

next_button = WebDriverWait(ff, 60).until(
    EC.visibility_of_element_located((By.XPATH, '(//li/a[contains(text(), "Next")])[1]'))
)

我也尝试过使用element_to_be_clickable。这两个最终都会超时。

【问题讨论】:

    标签: python selenium web-scraping web-crawler screen-scraping


    【解决方案1】:

    那是因为您正在尝试处理隐藏链接。请改用下面的方法

    next_button = ff.find_element_by_partial_link_text('Next')
    next_button.click()
    

    next _button = ff.find_element_by_link_text('Next→')
    

    请注意,find_element_by_partial_link_text/find_element_by_link_text 仅搜索 可见 链接。

    另外你可能需要打电话

    ff.implicitly_wait(10)
    

    在您的脚本中一次(在您的 WebDriver 实例定义之后的某处)或使用 ExplicitWait,如下所示

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    next_button = WebDriverWait(ff, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, 'Next→')))
    

    确保即使渲染延迟也能找到所需的元素

    【讨论】:

    • 但是按钮在DOM中是可见的而不是隐藏的?!?!那为什么我的方法不起作用?
    • 没有。 //li/a[contains(text(), "Next")])[1] 找到的按钮位于 div 内部,类名为 hidden。请注意,XPath 中的索引[1] 表示first。如果你想处理secondvisible)链接,你应该使用//li/a[contains(text(), "Next")])[2]。但正如我所说,通过链接文本搜索是更可靠的方式,因为它会忽略所有隐藏的链接......
    • 你错了,只有[2]有一个父级是hidden,那(//li/a[contains(text(), "Next")])[1]怎么不起作用??
    • (//li/a[contains(text(), "Next")])[1] 找到链接没有问题,但由于某种原因它无法滚动到视图中...
    • 不知道为什么你仍然不同意。第一个链接显然是隐藏的,第二个链接是可见的。如果你不相信我,试试print(dr.find_element_by_xpath('(//li/a[contains(text(), "Next")])[1]').is_displayed())print(dr.find_element_by_xpath('(//li/a[contains(text(), "Next")])[2]').is_displayed())
    猜你喜欢
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2022-01-23
    • 2017-07-28
    • 2019-08-11
    相关资源
    最近更新 更多