如何加载整个网站以供 selenium 从中收集数据,并保持所有内容加载?
How to load in the entirety of a website for selenium to collect data from, and keep everything loaded in?
我正在使用 python 中的 selenium chrome 驱动程序从以下网站抓取术语和定义:https://quizlet.com/433328443/ap-us-history-flash-cards/.有 533 个术语……事实上,如果您想查看所有术语,quizlet 会让您单击 See more
按钮。以下代码成功提取了术语和定义(我已经在其他术语较少的 quizlet 网站上对其进行了测试)。还有 if()
语句来处理弹出窗口和 See more
按钮。同样,我的目标是获取页面上每个术语定义对的术语和定义;但是,为此,需要加载整个页面,这是我问题的基础。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path = chrome_driver_path)
driver.get("https://quizlet.com/433328443/ap-us-history-flash-cards/")
# INCASE OF POPUP, CLICK AWAY
if len(driver.find_elements_by_xpath("//button[@class='UILink UILink--revert']")) > 0:
popup = driver.find_element_by_xpath("//button[@class='UILink UILink--revert']")
popup.click()
del popup
# SCROLL TO BOTTOM TO LOAD IN ALL TERMS, AND THEN BACK TO THE TOP
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# INCASE OF "SEE MORE" BUTTON AT BOTTOM, CLICK IT
if len(driver.find_elements_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")) > 0:
see_more = driver.find_element_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")
see_more.click()
del see_more
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# list of terms
quizlet_terms = tuple(map(lambda a: a.text,
driver.find_elements_by_class_name("SetPageTerm-wordText")))
# list of definitions
quizlet_definitions = tuple(map(lambda a: a.text,
driver.find_elements_by_class_name("SetPageTerm-definitionText")))
在我的代码中,我尝试了向下滚动技巧来加载所有内容,但这不起作用。这是因为当我向下滚动时,当我的浏览器 window 中的条款被加载时,浏览器 window 上方和下方的条款被卸载。显然,这样做是出于内存原因,但我不关心内存,我只想一次加载所有术语,以便我可以访问它们的内容。我的代码适用于较小的 quizlet 网站(比如 100 个术语),但它在此网站上中断,生成以下错误:
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
这个 Whosebug 页面解释了错误消息:。
通过阅读上述页面,我得出的结论是,由于网站太大,当我向下滚动 quizlet 页面时,我当前在浏览器中查看的术语 window 已加载,但是我已经滚动过去但不再在我的视图中的术语被卸载并以我无法正确访问的一些时髦方式存储,生成错误消息。
如何保持整个页面加载以便我可以访问所有 533 个术语的内容?理想情况下,我想要一个解决方案,让我滚动过去的所有内容都完全加载,并且不会卸载任何东西。另一个想法是从一开始就加载整个页面。如果有一些节省内存的解决方案也很好,也许只是访问原始 html
代码而不是花哨的图形或任何东西。有没有人遇到过这个问题,如果遇到过,您是如何解决的?谢谢,感谢您的帮助。
非常感谢@Abhishek Dhoundiyal
的评论。我的工作代码:
driver.execute_script("window.scrollTo(800, 800);")
terms_in_this_set = int(sub("\D", "", (driver.find_element_by_xpath("//h4[@class='UIHeading UIHeading--assembly UIHeading--four']")).text))
chunk_size = 15000
quizlet = numpy.empty(shape = (0, 2), dtype = "str")
# done in while loop so that terms and definitions can be extracted while scrolling (while making sure there are no duplicate entries)
while len(quizlet) != terms_in_this_set:
# INCASE OF "SEE MORE" BUTTON, CLICK IT TO SEE MORE
if len(driver.find_elements_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")) > 0:
see_more = driver.find_element_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")
see_more.click()
del see_more
# CHECK IF THERE ARE TERMS
quizlet_terms_classes = driver.find_elements_by_class_name("SetPageTerm-wordText")
quizlet_definitions_classes = driver.find_elements_by_class_name("SetPageTerm-definitionText")
if (len(quizlet_terms_classes) > 0) and (len(quizlet_definitions_classes) > 0):
# append current iteration terms and definitions to full quizlet terms and definitions
quizlet = numpy.vstack((quizlet, numpy.transpose([list(map(lambda term: remove_whitespace(term.text), quizlet_terms_classes)), list(map(lambda definition: remove_whitespace(definition.text), quizlet_definitions_classes))])))
# get unique rows
quizlet = numpy.unique(quizlet, axis = 0)
del quizlet_terms_classes, quizlet_definitions_classes
driver.execute_script(f"window.scrollBy(0, {chunk_size})")
del terms_in_this_set
我正在使用 python 中的 selenium chrome 驱动程序从以下网站抓取术语和定义:https://quizlet.com/433328443/ap-us-history-flash-cards/.有 533 个术语……事实上,如果您想查看所有术语,quizlet 会让您单击 See more
按钮。以下代码成功提取了术语和定义(我已经在其他术语较少的 quizlet 网站上对其进行了测试)。还有 if()
语句来处理弹出窗口和 See more
按钮。同样,我的目标是获取页面上每个术语定义对的术语和定义;但是,为此,需要加载整个页面,这是我问题的基础。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path = chrome_driver_path)
driver.get("https://quizlet.com/433328443/ap-us-history-flash-cards/")
# INCASE OF POPUP, CLICK AWAY
if len(driver.find_elements_by_xpath("//button[@class='UILink UILink--revert']")) > 0:
popup = driver.find_element_by_xpath("//button[@class='UILink UILink--revert']")
popup.click()
del popup
# SCROLL TO BOTTOM TO LOAD IN ALL TERMS, AND THEN BACK TO THE TOP
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# INCASE OF "SEE MORE" BUTTON AT BOTTOM, CLICK IT
if len(driver.find_elements_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")) > 0:
see_more = driver.find_element_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")
see_more.click()
del see_more
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# list of terms
quizlet_terms = tuple(map(lambda a: a.text,
driver.find_elements_by_class_name("SetPageTerm-wordText")))
# list of definitions
quizlet_definitions = tuple(map(lambda a: a.text,
driver.find_elements_by_class_name("SetPageTerm-definitionText")))
在我的代码中,我尝试了向下滚动技巧来加载所有内容,但这不起作用。这是因为当我向下滚动时,当我的浏览器 window 中的条款被加载时,浏览器 window 上方和下方的条款被卸载。显然,这样做是出于内存原因,但我不关心内存,我只想一次加载所有术语,以便我可以访问它们的内容。我的代码适用于较小的 quizlet 网站(比如 100 个术语),但它在此网站上中断,生成以下错误:
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
这个 Whosebug 页面解释了错误消息:
通过阅读上述页面,我得出的结论是,由于网站太大,当我向下滚动 quizlet 页面时,我当前在浏览器中查看的术语 window 已加载,但是我已经滚动过去但不再在我的视图中的术语被卸载并以我无法正确访问的一些时髦方式存储,生成错误消息。
如何保持整个页面加载以便我可以访问所有 533 个术语的内容?理想情况下,我想要一个解决方案,让我滚动过去的所有内容都完全加载,并且不会卸载任何东西。另一个想法是从一开始就加载整个页面。如果有一些节省内存的解决方案也很好,也许只是访问原始 html
代码而不是花哨的图形或任何东西。有没有人遇到过这个问题,如果遇到过,您是如何解决的?谢谢,感谢您的帮助。
非常感谢@Abhishek Dhoundiyal
的评论。我的工作代码:
driver.execute_script("window.scrollTo(800, 800);")
terms_in_this_set = int(sub("\D", "", (driver.find_element_by_xpath("//h4[@class='UIHeading UIHeading--assembly UIHeading--four']")).text))
chunk_size = 15000
quizlet = numpy.empty(shape = (0, 2), dtype = "str")
# done in while loop so that terms and definitions can be extracted while scrolling (while making sure there are no duplicate entries)
while len(quizlet) != terms_in_this_set:
# INCASE OF "SEE MORE" BUTTON, CLICK IT TO SEE MORE
if len(driver.find_elements_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")) > 0:
see_more = driver.find_element_by_xpath("//button[@class='UIButton UIButton--fill' and @aria-label='See more']")
see_more.click()
del see_more
# CHECK IF THERE ARE TERMS
quizlet_terms_classes = driver.find_elements_by_class_name("SetPageTerm-wordText")
quizlet_definitions_classes = driver.find_elements_by_class_name("SetPageTerm-definitionText")
if (len(quizlet_terms_classes) > 0) and (len(quizlet_definitions_classes) > 0):
# append current iteration terms and definitions to full quizlet terms and definitions
quizlet = numpy.vstack((quizlet, numpy.transpose([list(map(lambda term: remove_whitespace(term.text), quizlet_terms_classes)), list(map(lambda definition: remove_whitespace(definition.text), quizlet_definitions_classes))])))
# get unique rows
quizlet = numpy.unique(quizlet, axis = 0)
del quizlet_terms_classes, quizlet_definitions_classes
driver.execute_script(f"window.scrollBy(0, {chunk_size})")
del terms_in_this_set