我已经使用python和selenium创建了一个脚本,以在下面的链接中获取所有可用的文本。该网页已启用了惰性加载方法,这就是为什么每次滚动时都可以看到更多内容的原因。我的脚本也可以处理。
但是,问题是当我的脚本使网页到达底部时耗尽了其内容时,它卡在了那里。一旦可以打破循环,我就可以获取内容。我该如何跳出循环?
我知道.LoadingDots
一直在那儿。这是我找不到打破循环的逻辑的唯一原因。
这是到目前为止我尝试过的:(无法摆脱循环)
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)
driver.get("https://www.quora.com/topic/American-Football")
while True:
try:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".LoadingDots")))
except Exception: break
for item in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".ui_qtext_rendered_qtext .ui_qtext_para"))):
print(item.text)
driver.quit()
我知道我可以解决以下问题:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)
driver.get("https://www.quora.com/topic/American-Football")
last_len = len(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".ui_qtext_rendered_qtext .ui_qtext_para"))))
while True:
for load_more in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "a[id$='_more']"))):
driver.execute_script("arguments[0].click();",load_more)
try:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
wait.until(lambda driver: len(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".ui_qtext_rendered_qtext .ui_qtext_para")))) > last_len)
items = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".ui_qtext_rendered_qtext .ui_qtext_para")))
last_len = len(items)
except TimeoutException: break
for item in items:
print(item.text)
driver.quit()
我的问题是:我该如何使用我使用.LoadingDots
的第一个脚本尝试的方式从该页面中耗尽所有滚动的内容?
答案 0 :(得分:2)
将页面滚动到按钮时,具有类.LoadingDots.regular
的元素保持不变,但是其父元素添加了新的类hidden
。您可以检查是否使用get_attribute
函数添加了该类。您也可以直接在类spinner_display_area
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
loading_dots = driver.find_element_by_class_name('spinner_display_area')
if 'hidden' in loading_dots.get_attribute('class'):
break;
答案 1 :(得分:0)
您的脚本无法按预期运行,因为(By.CSS_SELECTOR, ".LoadingDots")
选择器返回了该元素<div class="LoadingDots tiny">
,并且该元素始终隐藏,因此您期望其隐身始终返回True
,并且循环不能中断。
您需要检查具有"LoadingDots"
类名称的另一个元素:<div class="LoadingDots regular">
,并且逻辑应遵循以下条件:
如果在页面滚动后我们看不到点-中断循环
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 5)
driver.get("https://www.quora.com/topic/American-Football")
while True:
try:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".LoadingDots.regular")))
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".LoadingDots.regular")))
except Exception: continue
else: break
for item in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".ui_qtext_rendered_qtext .ui_qtext_para"))):
print(item.text)
driver.quit()
但是!请注意,我发布此脚本只是为了指出您的脚本无法正常工作的原因...效率不高,因为如果内容加载速度太快(可能性很低,但是...),脚本可能无法及时解决当加载点出现时,您将无法获得所有必需的内容。
所以@Guy解决方案似乎更可靠(+1)