You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Selenium与Python点击JavaScript驱动的点赞按钮失败问题求助

Hey there, let's break down why your Selenium script isn't hitting that like button and fix it step by step!

First, let's look at the key issues in your current code:

  • Fragile absolute XPath: Your current XPath (//*[@id='30247788']/div[5]/div/div/ul/li[1]/a/i) relies heavily on the exact structure of the page. Angular apps (which this looks like, with those ng-* attributes) often have dynamic elements, and small changes to the DOM or dynamic IDs will break this path instantly.
  • Insufficient waiting: Using time.sleep(3) is a gamble—sometimes the page (especially Angular-rendered content) takes longer to load elements. Hardcoded sleeps aren't reliable for dynamic pages.
  • Missing login step: Webtalk requires you to be logged in to interact with posts. Without logging in, the like button might not even be visible or interactive.
  • Angular ngIf constraint: The <i> element you're targeting only exists when !$ctrl.postData.is_liked (i.e., the post hasn't been liked yet). If the post is already liked, this element won't be in the DOM, leading to a NoSuchElementException.

Here's a revised script that addresses all these issues:

First, make sure you import the necessary Selenium wait utilities:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time

Then, update your code to use stable locators, explicit waits, and handle login + edge cases:

PATH = r"C:\Program Files (x86)\chromedriver_win32\chromedriver.exe"  # Use raw string to avoid escape issues
driver = webdriver.Chrome(PATH)
driver.get("https://www.webtalk.co/")
driver.maximize_window()

# --------------------------
# Step 1: Add Login Logic (REQUIRED)
# You'll need to fill in your own Webtalk credentials here
# --------------------------
try:
    # Wait for login elements to load (adjust selectors if needed based on the actual login page)
    username_field = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "username"))  # Replace with actual username field ID/selector
    )
    username_field.send_keys("your_webtalk_username")
    
    password_field = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "password"))  # Replace with actual password field ID/selector
    )
    password_field.send_keys("your_webtalk_password")
    
    # Click login button
    login_button = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Login')]"))  # Adjust selector if needed
    )
    login_button.click()
    
    # Wait for post feed to load after login
    time.sleep(3)  # Optional, but can help if the feed takes a moment to render
except Exception as e:
    print(f"Login failed: {str(e)}")
    driver.quit()
    exit()

# --------------------------
# Step 2: Locate and Click the Like Button
# --------------------------
try:
    # Use a stable relative XPath targeting the Like icon directly
    like_button = WebDriverWait(driver, 15).until(
        EC.element_to_be_clickable((By.XPATH, "//i[@class='icon icon-post-like private-link' and text()='Like']"))
    )
    like_button.click()
    print("Successfully liked the post!")
except Exception as e:
    # Check if the post is already liked (since the Like element won't exist anymore)
    try:
        WebDriverWait(driver, 5).until(
            EC.presence_of_element_located((By.XPATH, "//li[contains(@ng-class, 'selected') and contains(@class, 'liked-desk')]"))
        )
        print("This post is already liked!")
    except Exception as e2:
        print(f"Could not interact with the like button: {str(e2)}")
        print("Possible reasons: Post not loaded, login failed, or element selector needs adjustment.")

driver.quit()

Key improvements explained:

  1. Stable Locators: The new XPath targets the Like icon using its class and text content, which is far less likely to break than an absolute path. Alternatively, you could target the parent <a> tag using its ng-click attribute: //a[contains(@ng-click, 'likeMedia')]/i[text()='Like'].
  2. Explicit Waits: WebDriverWait waits up to the specified time for the element to be clickable, which is way more reliable than time.sleep for dynamic Angular pages.
  3. Login Handling: Added a login section (you'll need to tweak the selectors to match the actual Webtalk login page) because you can't like posts without being logged in.
  4. Edge Case Handling: If the post is already liked, the script detects the "liked" state instead of throwing an unhandled error.

Additional Tips:

  • If the element is still not found, open the browser's dev tools and verify:
    • Are you logged in when the script runs?
    • Does the Like element's class/text match the selector?
    • Is the element inside an iframe? (Unlikely here, but worth checking)
  • Avoid absolute XPaths whenever possible—use relative paths based on unique attributes like ng-click, class names, or text.

内容的提问来源于stack exchange,提问作者Akif Ejaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:17:36