我使用python软件包selenium自动单击“加载更多”按钮,这是成功的。但是,为什么在“加载更多”后无法获取数据?
我想使用python从imdb检索评论。它只显示25条评论,直到我单击“加载更多”按钮。我使用python软件包selenium自动单击“加载更多”按钮,这是成功的。但是,为什么我在“加载更多”后无法获取数据,而只是重复获取前25条评论数据?
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
import time
seed = 'https://www.imdb.com/title/tt4209788/reviews'
movie_review = requests.get(seed)
PATIENCE_TIME = 60
LOAD_MORE_BUTTON_XPATH = '//*[@id="browse-itemsprimary"]/li[2]/button/span/span[2]'
driver = webdriver.Chrome('D:/chromedriver_win32/chromedriver.exe')
driver.get(seed)
while True:
try:
loadMoreButton = driver.find_element_by_xpath("//button[@class='ipl-load-more__button']")
review_soup = BeautifulSoup(movie_review.text, 'html.parser')
review_containers = review_soup.find_all('div', class_ ='imdb-user-review')
print('length: ',len(review_containers))
for review_container in review_containers:
review_title = review_container.find('a', class_ = 'title').text
print(review_title)
time.sleep(2)
loadMoreButton.click()
time.sleep(5)
except Exception as e:
print(e)
break
print("Complete")
我想要所有评论,但现在我只能得到前25条。
答案 0 :(得分:2)
您的脚本中有几个问题。硬编码的等待非常不一致,并且肯定是最糟糕的选择。在while True:
循环中编写抓取逻辑的方式将一遍又一遍地收集相同的项目,从而减慢了解析过程。而且,每个标题都会在输出中产生巨大的行间隙,需要适当地剥离。我对您的脚本进行了些微更改,以反映出我上面给出的建议。
尝试此操作以获取所需的输出:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
URL = "https://www.imdb.com/title/tt4209788/reviews"
driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)
driver.get(URL)
soup = BeautifulSoup(driver.page_source, 'lxml')
while True:
try:
driver.find_element_by_css_selector("button#load-more-trigger").click()
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR,".ipl-load-more__load-indicator")))
soup = BeautifulSoup(driver.page_source, 'lxml')
except Exception:break
for elem in soup.find_all(class_='imdb-user-review'):
name = elem.find(class_='title').get_text(strip=True)
print(name)
driver.quit()
答案 1 :(得分:0)
您的代码很好。太好了。但是,在单击“加载更多”按钮后,您再也不会获取网页的“更新的” HTML。这就是为什么您总是得到相同的25条评论的原因。
使用Selenium来控制Web浏览器时,您正在单击“加载更多”按钮。这将创建一个XHR请求(或更常用的AJAX请求),您可以在Web浏览器开发人员工具的“网络”标签中看到该请求。
最重要的是JavaScript(在网络浏览器中运行 )更新了页面。但是在您的Python程序中,您只能使用请求库静态获取页面的HTML 一次。
seed = 'https://www.imdb.com/title/tt4209788/reviews'
movie_review = requests.get(seed) #<-- SEE HERE? This is always the same HTML. You fetched in once in the beginning.
PATIENCE_TIME = 60
要解决此问题,您需要使用Selenium来获取包含评论的div框的innerHTML。然后,让BeautifulSoup再次解析HTML。我们希望避免一次又一次地拾取整个页面的HTML,因为它需要计算资源才能一遍又一遍地解析更新的HTML。
因此,在包含评论的页面上找到div,然后使用BeautifulSoup再次对其进行解析。这样的事情应该起作用:
while True:
try:
allReviewsDiv = driver.find_element_by_xpath("//div[@class='lister-list']")
allReviewsHTML = allReviewsDiv.get_attribute('innerHTML')
loadMoreButton = driver.find_element_by_xpath("//button[@class='ipl-load-more__button']")
review_soup = BeautifulSoup(allReviewsHTML, 'html.parser')
review_containers = review_soup.find_all('div', class_ ='imdb-user-review')
pdb.set_trace()
print('length: ',len(review_containers))
for review_container in review_containers:
review_title = review_container.find('a', class_ = 'title').text
print(review_title)
time.sleep(2)
loadMoreButton.click()
time.sleep(5)
except Exception as e:
print(e)
break