英文:
Unable to click button Selenium Python
问题
I am web-scraping reviews from Goodreads for a project. Here's an example of a page I've been trying: https://www.goodreads.com/book/show/2767052-the-hunger-games/reviews?
The reviews page initially shows 30 reviews with a 'Show More' button at the bottom. Selenium seems unable to click the button.
Here is the code I'm using:
showmore_button = driver.find_element(By.XPATH, '/html/body/div[1]/div/main/div[1]/div[2]/div[4]/div[4]/div/button/span[1]')
driver.execute_script("arguments[0].click();", showmore_button)
I have also tried showmore_button.click()
but that leads to an exception stating that the element is not clickable.
For more context my driver is set up like this:
def createdriver():
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument("start-maximized")
options.add_argument('--window-size=1920,1080')
options.add_argument("--incognito")
driver = webdriver.Chrome(options=options)
return driver
and then I use:
driver = createdriver()
driver.get(url)
Where the URL is the reviews page I'm trying to scrape
英文:
I am web-scraping reviews from Goodreads for a project. Here's an example of a page I've been trying: https://www.goodreads.com/book/show/2767052-the-hunger-games/reviews?
The reviews page initially shows 30 reviews with a 'Show More' button at the bottom. Selenium seems unable to click the button.
Here is the code I'm using:
showmore_button = driver.find_element(By.XPATH, '/html/body/div[1]/div/main/div[1]/div[2]/div[4]/div[4]/div/button/span[1]')
driver.execute_script("arguments[0].click();", showmore_button)
I have also tried
showmore_button.click()
but that leads to an exception stating that the element is not clickable
For more context my driver is set up like this:
def createdriver():
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument("start-maximized")
options.add_argument('--window-size=1920,1080')
options.add_argument("--incognito")
driver = webdriver.Chrome(options=options)
return driver
and then I use:
driver = createdriver()
driver.get(url)
Where the URL is the reviews page I'm trying to scrape
答案1
得分: 0
如页面在元素显示之前加载了几毫秒,您需要使用Selenium等待。在创建驱动程序实例后,尝试使用隐式等待,请参考以下代码:
driver = createdriver()
driver.implicitly_wait(10)
driver.get(url)
上述代码在抛出错误之前等待10秒钟以查找元素。
另一个建议:
不要使用绝对XPath,最好使用相对XPath作为最佳实践。这是因为相对XPath与绝对XPath相比更一致。如果将来DOM结构发生更改,绝对XPath可能停止工作。尝试以下相对XPath:
showmore_button = driver.find_element(By.XPATH, '//span[contains(text(),"Show more reviews")]')
driver.execute_script("arguments[0].click();", showmore_button)
英文:
As the page loads for few milli-seconds before the element is displayed, you need to apply selenium waits. Try using implicit wait after creating the driver instance, see code below:
driver = createdriver()
driver.implicitly_wait(10)
driver.get(url)
Above code waits for 10 seconds searching for the element before throwing error
Also another suggestion:
Instead of using an absolute XPath, as a best practice use relative XPath. This is because relative XPath is more consistent compared to absolute XPath. Absolute XPath may stop working, If the DOM structure changes in the future. Try the below relative XPath:
showmore_button = driver.find_element(By.XPATH, '//span[contains(text(),"Show more reviews")]')
driver.execute_script("arguments[0].click();", showmore_button)
答案2
得分: 0
点击页面底部的<kbd>显示更多评论</kbd>元素需要使用scrollIntoView()
引发WebDriverWait来等待visibility_of_element_located(),您可以使用以下定位策略:
- 代码块:
driver.get('https://www.goodreads.com/book/show/2767052-the-hunger-games/reviews?')
time.sleep(5)
driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='ReviewsList__listContext ReviewsList__listContext--centered']//span[contains(., 'Displaying 1 -')]")))
driver.execute_script("arguments[0].click();", driver.find_element(By.XPATH, "//span[text()='Show more reviews']"))
- 注意:您需要添加以下导入:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
- 浏览器截图:
英文:
To click on the element <kbd>Show more reviews</kbd> at the bottom of the page you need to scrollIntoView()
inducing WebDriverWait for the visibility_of_element_located() and you can use the following locator strategies:
-
Code block:
driver.get('https://www.goodreads.com/book/show/2767052-the-hunger-games/reviews?') time.sleep(5) driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='ReviewsList__listContext ReviewsList__listContext--centered']//span[contains(., 'Displaying 1 -')]")))) driver.execute_script("arguments[0].click();", driver.find_element(By.XPATH, "//span[text()='Show more reviews']"))
-
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC
-
Browser snapshot:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论