【问题标题】:How to load all comments of a website via selenium in python如何通过python中的selenium加载网站的所有评论
【发布时间】:2020-04-15 10:56:55
【问题描述】:

我想从https://www.focus.de/gesundheit/news/coronavirus-news-trump-prahlt-mit-allumfassender-macht_id_11576018.html 刮取所有 cmets (~7000)。由于该网站没有显示所有 cmets,但只提供了一次加载 10 个 cmets 的可能性,我尝试在 python 中使用 selenium 加载所有 cmets,然后将输出提供给 BeautifulSoup。

与按钮“Weitere Kommentare (10)”相对应并加载接下来的 10 个 cmets 的网站 HTML 片段是:

<div id="further_comments" class="getMoreComments">                 
    <a rel="1" class="moreComments bluebutton">
         <span>Weitere Kommentare (10)</span>
    </a>                        
</div>

它会加载接下来的 10 个 cmets(下面的第二个 div,这里只显示一个而不是 10 个)和一个用于加载另外 10 个 cmets 的新按钮 (a):

<div class="moreComments">
    <div class="comment clearfix open oid-15051615"</div>
    <div class="getMoreComments">
        <a class="moreCommentsAjx bluebutton" rel="1"></a>
    </div>
</div>

我的方法是编写一个自动单击“Weitere Kommentare (10)”的脚本,等待下一个 10 cmets 并加载下一个按钮“Weitere Kommentare (10)”,找到该按钮,再次单击它。 . 直到所有 cmets 都加载完毕。我的尝试如下(我将按钮居中以避免页面底部的弹出窗口,这会掩盖按钮):

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 StaleElementReferenceException, NoSuchElementException

ignored_exceptions = (NoSuchElementException, StaleElementReferenceException)

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get('https://www.focus.de/gesundheit/news/coronavirus-news-trump-prahlt-mit-allumfassender-macht_id_11576018.html')
driver.fullscreen_window()

button = driver.find_element_by_class_name("moreComments.bluebutton")
driver.execute_script('arguments[0].scrollIntoView({block: "center", inline: "center"})', button)
driver.execute_script("arguments[0].click();", button)

while driver.find_element_by_class_name("moreCommentsAjx.bluebutton"):
    element = WebDriverWait(driver, 10, ignored_exceptions=ignored_exceptions).until(EC.visibility_of_element_located((By.CLASS_NAME, "moreCommentsAjx.bluebutton")))
    driver.execute_script('arguments[0].scrollIntoView({block: "center", inline: "center"})', element)
    element.click()

page_source = driver.page_source

不幸的是,该代码从未通过。在某些时候,按钮“Weitere Kommentare (10)”不再出现,并且抛出“NoSuchElementException:无法定位元素:.moreCommentsAjx.bluebutton”(奇怪的是,尽管它应该忽略它)。令我困惑的是,它不是系统的。有时它会在失败之前设法加载几百个 cmets,有时只有 30 个等。偶尔会抛出一个 StaleElementReferenceException(再次它不应该,但确实如此),当滚动似乎失败并且没有使按钮居中时,但这很少.

提前感谢您的帮助。

【问题讨论】:

  • 哪里失败了?在 while 行还是在您等待的行中?
  • @INDIVIDUAL-IT element.click() 失败,这很奇怪。最初它找到了元素,因为它进入了 while 循环,但在循环中元素不再存在(网站不显示按钮)。
  • 在下面查看我的答案 (stackoverflow.com/a/61227265/4501350)

标签: python selenium selenium-webdriver web-scraping


【解决方案1】:

您可能“错误地”等待

单击后,您等待按钮出现,但它可能仍然存在并且尚未消失。

单击后,您想等到按钮消失(但不会失败并且超时时间很短),然后您想等到按钮再次出现。

【讨论】:

  • 如果我理解正确,那么在 element.click() 之后添加 time.sleep (我尝试了 3 秒)可以解决问题,但遗憾的是它没有。再次在某个(随机)时间点,网站上没有出现新按钮,点击失败。
  • 点击前尝试等待element_to_be_clickable,点击后invisibility_of_element_locatedselenium-python.readthedocs.io/waits.html我不会忽略点击前等待中的异常,你想知道等待是否失败出于某种原因,点击后的等待应该有一个低超时,例如5 秒(所以你最多浪费 5 秒),如果按钮来得更快,你可以忽略异常
  • 在点击后添加WebDriverWait(driver, 5).until(EC.invisibility_of_element_located((By.CLASS_NAME,"moreCommentsAjx.bluebutton"))) 会给我一个超时。显然,新按钮加载速度如此之快,以至于它永远不会隐形。我读到这可能是由于 driver.implicitly_wait,但删除它并不会改变这一点。
  • 尝试忽略超时异常,实际上是在抛出异常吗?
  • 如果我尝试忽略超时,我会得到“TypeError: __init__() got an unexpected keyword argument 'ignored_exception'”。我可以赶上超时,但我不知道这是否能让我更进一步。
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 2015-03-05
  • 2020-10-05
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
相关资源
最近更新 更多