繁体   English   中英

为什么我在使用 selenium 时只获取首页数据?

[英]Why do I only get first page data when using selenium?

我使用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 条。

您的脚本中有几个问题。 硬编码等待非常不一致,当然是最糟糕的选择。 您在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()

你的代码没问题。 甚至很棒。 但是,您永远不会在点击“加载更多”按钮后获取网页的“更新”HTML。 这就是为什么您总是收到相同的 25 条评论。

当您使用 Selenium 控制 Web 浏览器时,您正在单击“加载更多”按钮。 这将创建一个 XHR 请求(或更常见的称为 AJAX 请求),您可以在 Web 浏览器的开发人员工具的“网络”选项卡中看到该请求。

底线是 JavaScript(在 Web 浏览器中运行)更新页面。 但是在您的 Python 程序中,您只能使用 Requests 库静态地获取页面的 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM