【问题标题】:Not Selecting All Elements Though All Are Detected尽管检测到所有元素,但未选择所有元素
【发布时间】:2018-07-25 02:37:05
【问题描述】:

我有一个脚本,可以在this page 底部单击“显示更多”四次以显示更多评论线程。

即使我的XPATH 将选择所有“查看更多回复.../查看更多回复...”元素,脚本也不会最终单击所有这些元素。 (在撰写本文时,它只点击了 13 个元素中的 7 个。)

XPath 选择器

//ui-view//a[contains(@class, "commentAction")]

脚本部分(很长,如果您想/需要看更多内容,请告诉我。):

tab_comments = browser.find_elements_by_xpath('//a[@gogo-test="comments_tab"]')

if len(tab_comments) > 0:

    browser.implicitly_wait(5)

    try:
        comments_count = int(''.join(filter(str.isdigit, str(tab_comments[0].text))))
    except ValueError:
        comments_count = 0

    if comments_count > 0:
        # 1. Switch to Comments Tab
        tab_comments[0].click()

        # 2. Expose Additional Threads
        show_more_comments = WebDriverWait(browser, 10).until(
            EC.element_to_be_clickable((By.XPATH, '//ui-view//a[text()="show more"]'))
        )

        clicks = 0
        while clicks <= 3:
            try:
                clicks += 1
                show_more_comments.click()
            except Exception:
                break

        # 3. Expand All Threads
        see_n_more_replies = browser.find_elements_by_xpath('//ui-view//a[contains(@class, "commentAction")]')
        for idx, see_replies in enumerate(see_n_more_replies):
            print('\n\n\n\nidx: ' + str(idx) + '\n\n\n\n')
            see_replies.click()

按钮是否需要在视图中才能单击它们?(其他按钮似乎不是这种情况,但此时我正在抓住稻草。 )

问题是我在步骤# 4. ... 中解析了 cmets,并且由于它不会以多个响应扩展所有线程,这是它应该做的,这些字段在日志中变为空.

不会引发错误或异常。

我正在使用 Firefox/geckodriver。

【问题讨论】:

    标签: python selenium selenium-webdriver xpath geckodriver


    【解决方案1】:

    执行以下代码sn-p,通过点击“显示更多”,加载页面上的所有cmets,直到显示更多链接消失

    comment_pages = 0
    no_of_comments = len(driver.find_elements_by_tag_name('desktop-comment'))
    while True:
        show_more_link = driver.find_elements_by_partial_link_text('show more')
        if len(show_more_link) == 0:  # if the 'show more' link does not exist on the page
            break
        # before clicking on the link, it is important to bring the link inside the viewport. Otherwise `ElementNotVisible` exception is encountered
        driver.execute_script('arguments[0].scrollIntoView(true);', show_more_link[0])
        show_more_link[0].click()
        try:
            # wait for more comments to load by waiting till the comment count after clicking the button is greater than before the click
            WebDriverWait(driver, 10, poll_frequency=2).until(lambda x: len(driver.find_elements_by_tag_name('desktop-comment')) > no_of_comments)
        except:
            break
        no_of_comments = len(driver.find_elements_by_tag_name('desktop-comment'))
        comment_pages += 1
    

    执行此代码后,您的 dom 包含所有 cmets 的内容。发布您开始实际抓取页面的帖子。

    comments = driver.find_elements_by_tag_name('desktop-comment')
    for comment in comments:
        author = comment.find_element_by_xpath(".//div[@class='commentLayout-header']/a[contains(@href, 'individuals')]").text
        print 'Comment by person : ' + author
    
        has_more_replies = len(comment.find_elements_by_partial_link_text("more replies...")) > 0
        if has_more_replies:
            more_replies = comment.find_element_by_partial_link_text("more replies...")
            driver.execute_script('arguments[0].scrollIntoView()', more_replies)
            more_replies.click()
        reply_count = len(comment.find_elements_by_xpath(".//div[contains(@class, 'commentLayout-reply')]"))
        print 'Number of replies to the comment : ' + str(reply_count)
        print '-------------------------------------------------------------------'
    

    其输出如下:

    Comment by person : Jeff Rudd
    Number of replies to the comment : 1
    -------------------------------------------------------------------
    Comment by person : Martin Boyle
    Number of replies to the comment : 1
    -------------------------------------------------------------------
    Comment by person : John Bickerton
    Number of replies to the comment : 1
    -------------------------------------------------------------------
    Comment by person : Mikkel Taanning
    Number of replies to the comment : 2
    -------------------------------------------------------------------
    Comment by person : Christopher Sams
    Number of replies to the comment : 2
    -------------------------------------------------------------------
    Comment by person : Marc Vieux
    Number of replies to the comment : 2
    -------------------------------------------------------------------
    

    .......................

    您可以修改 for 循环以获取有关 cmets 的更多详细信息

    【讨论】:

    • 如果不想使用JS的scrollIntoView方法,可以使用ActionChains类中的move_to_element方法。它不应该有所作为。要回答您的其他问题,是的,我已经对此进行了测试,是的,它实际上返回了所有元素。我在回答中截断了输出以保持简洁。在执行单击之前将move_to_element 添加到您的代码中,看看是否有帮助。
    • 我想知道为什么要使用 javascript?你测试过我提供的代码吗?我想知道为什么该代码不起作用?我真的必须将项目滚动到视图中,以便它们可以用 selenium 进行点击吗?
    • 我之前的评论中没有提到 JavaScript 的替代方案吗?- 使用 move_to_element。我会在某个时候测试你的代码并回复你。使用 selenium Web 驱动程序时必须记住的一件事是它模拟页面上的用户操作(或至少尝试)。因此,用户要点击某物,首先需要看到它。我很好奇您对将项目滚动到视图中的保留是什么。
    • 哦,哎呀,直到现在我才真正看过你的代码,我只是假设你用 javascript 做的比你实际做的要多得多。我的问题仍然存在:是否需要将每个元素滚动到视图中?如果在单击之前移动到元素有效,则将此标记为答案
    • 确保在代码中添加适当的等待。例如:在您的 while 循环中,您快速连续点击“显示更多”链接 4 次,而无需等待 UI 响应您的点击。这应该避免,可以通过在代码中添加显式等待来处理。 scrollIntoViewmove_to_element 使代码更不受讨厌的 ElementNotVisibleException 的影响。
    猜你喜欢
    • 1970-01-01
    • 2013-04-21
    • 2017-08-10
    • 2012-01-15
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多