在 Python 中使用 Selenium 滚动模式窗口

Posted

技术标签:

【中文标题】在 Python 中使用 Selenium 滚动模式窗口【英文标题】:Scroll modal window using Selenium in Python 【发布时间】:2017-10-25 13:04:21 【问题描述】:

我正在尝试为genius.com 上的一些艺术家抓取指向歌曲页面的链接,但我遇到了问题,因为指向各个歌曲页面的链接显示在弹出模式窗口中。

模态窗口不会一次性加载所有链接,而是在您向下滚动到模态窗口底部时通过 ajax 加载更多内容。

我尝试使用代码滚动到页面底部,但不幸的是,它只是在模式后面的窗口中滚动,而不是在模式本身:

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

然后我尝试选择模式中的最后一个元素并滚动到该元素(我的想法是这样做几次,直到所有歌曲页面都加载完毕),但滚动的距离不足以让网站加载更多内容

last_element = driver.find_elements_by_xpath('//div[@class="mini_card-metadata"]')[-1]
last_element.location_once_scrolled_into_view

到目前为止,这是我的代码:

import os
from bs4 import BeautifulSoup
from selenium import webdriver

chrome_driver = "/Applications/chromedriver"
os.environ["webdriver.chrome.driver"] = chrome_driver
driver = webdriver.Chrome(chrome_driver)

base_url = 'https://genius.com/artists/Stormzy'
driver.get(base_url)

xpath_str = '//div[contains(text(),"Show all songs by Stormzy")]'
driver.find_element_by_xpath(xpath_str).click()

有没有办法为艺术家提取所有歌曲页面链接?

【问题讨论】:

请参阅:How do I do X? SO 的期望是,提出问题的用户不仅会进行研究以回答他们自己的问题,还会分享研究、代码尝试和结果。这表明您已经花时间尝试帮助自己,它使我们免于重复明显的答案,最重要的是它可以帮助您获得更具体和相关的答案!另见:How to Ask 【参考方案1】:

尝试下面的代码以获得所需的输出:

from selenium import webdriver as web
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException

driver = web.Chrome()
base_url = 'https://genius.com/artists/Stormzy'
driver.get(base_url)

# Open modal
driver.find_element_by_xpath('//div[normalize-space()="Show all songs by Stormzy"]').click()
song_locator = By.CSS_SELECTOR, 'a.mini_card.mini_card--small'
# Wait for first XHR complete
wait(driver, 10).until(EC.visibility_of_element_located(song_locator))
# Get current length of songs list
current_len = len(driver.find_elements(*song_locator))

while True:
    # Load new XHR until it's possible
    driver.find_element(*song_locator).send_keys(Keys.END)
    try:
        wait(driver, 3).until(lambda x: len(driver.find_elements(*song_locator)) > current_len)
        current_len = len(driver.find_elements(*song_locator))
    # Return full list of songs
    except TimeoutException:
        songs_list = [song.get_attribute('href') for song in driver.find_elements(*song_locator)]
        break

print(songs_list)

这应该允许您请求新的XHR,直到歌曲列表的长度变得恒定并最终返回链接列表

【讨论】:

【参考方案2】:

当你滚动到模态对话框的底部时,它会调用

$scrollable_data_ctrl.load_next();

作为选项,您可以尝试执行它,直到新结果出现在模态中

driver.execute_script("$scrollable_data_ctrl.load_next();")

【讨论】:

以上是关于在 Python 中使用 Selenium 滚动模式窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中使用 selenium 滚动到页面末尾?

九Python+Selenium模拟用QQ登陆腾讯课堂,并提取报名课程(练习)

Selenium/python:每次滚动后从动态加载的网页中提取文本

如何使用 python Selenium webdriver 滚动加载在网页中的 PDF?

Selenium 窗口滚动仅适用于使用 Selenium 和 Python 识别 Select 元素的调试模式

Python selenium 滚动条