在 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?