单击所有按钮并在出现错误异常时跳过一个按钮,然后继续单击所有按钮。异常执行后,不是所有的按钮都被点击

Click all buttons and skip one when I get error exception,then continue clicking all of them. After exception is executed, not all buttons are clicked

我向您展示了一些可执行的、可运行的和 GUI 代码,仅供学习之用。

我在 except 之后的自动点击有问题,准确地说,在异常 ElementClickInterceptedException 之后,我想在 While 循环中继续自动点击代码,但总是尊重设置的按钮数量来点击(limit)。问题是自从我得到异常后,并不是所有的按钮集都被点击了。基本上,如果我设置 20 次有限制的点击,脚本似乎可以正常工作,直到我得到异常。异常发生后,脚本仍会继续点击某些按钮,但不会点击 20。我不明白问题出在哪里。可能有多种原因。这是困扰我的部分(下面是完整的代码):

limit = int(number_requests.get())

i = 1
x = 1
        
while i <= limit:
    i = i + 1
        
    try:
        #These are the staves of the button list, useful for scrolling down. Each staff is a button
        row = wait.until(EC.visibility_of_element_located((By.XPATH, f"(//div[@data-visualcompletion='ignore-dynamic' and not (@role) and not (@class)])[{i}]")))
        #click on button
        add = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Add Friend']"))).click()
        
        #vertical scroll down 
        driver.execute_script("arguments[0].scrollIntoView(true);", row)
        time.sleep(delay)
        
        
        
    except ElementClickInterceptedException:
        print("This button could not be clicked")
        
        close_popup = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Ok']"))).click()
        
        while True:
            x = x + 2
            row_skip = wait.until(EC.visibility_of_element_located((By.XPATH, f"(//div[@data-visualcompletion='ignore-dynamic' and not (@role) and not (@class)])[{x}]")))
            addd_skip = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Add Friend']"))).click()
            break

注意:您会想知道“行”中的 xpath 是什么?下面,在下面,我解释一下“行”中的 xpath 是什么,并显示屏幕截图

我的代码是做什么的? 我向您展示的代码几乎一切正常,但有问题。它是这样工作的:

  1. 自动点击每个按钮(设置延迟和点击按钮的数量)
  2. 当您单击按钮时,按钮列表会随着垂直滚动条向下滚动
  3. 当我收到 ElementClickInterceptedException 错误时,弹出窗口自动关闭(单击“确定”关闭)
  4. Return到按钮列表并跳过一个按钮(1个,只有一个)
  5. 我继续 While 循环代码(包括 limit),然后我继续点击每个按钮,如果出现 ElementClickInterceptedException 错误,它 returns 指向第 3、4 和 5。

我的代码一开始工作正常,然后出现问题,虽然我不明白到底是哪一个。

WHAT DO I WANT TO GET? 代码的目的是当我得到一个 ElementClickInterceptedException 并继续点击其他按钮时跳过一个按钮(1,只有一个)在限制中设置的数量的 RESPECT 异常之后。为什么我要在第二个 While 的异常中跳过一个按钮?

问题: 如果我将 20 个按钮设置为点击,它们实际上并没有点击 20 个按钮,而是实际上并没有点击,例如只有 11 或 12 个按钮。此外,垂直滚动条似乎也有问题(即使我的代码看起来是正确的),因为滚动条只下降了一点,然后停止,所以它不显示任何其他按钮。

我的想法是,问题可能是以下之一:滚动条滚动有问题(它只向下滚动一点点,然后停止),或者“limit”输入错误的地方,或者以错误的方式,或者当我遇到异常时,它会在“try”代码中产生问题(我也尝试过 finally,但没有解决方案),或者我不知道它可能是什么其他问题

注意,非常重要:为什么在异常中进行第二次循环?当弹出窗口关闭时,脚本将继续单击按钮,但最后一个按钮它到达了异常将将其名称从“取消请求”更改为“添加朋友”。因此,脚本将继续无休止地单击同一个按钮,因为弹出窗口将打开,然后弹出窗口将关闭,然后按钮将更改其名称,将被单击并再次打开弹出窗口。

我该如何解决?完整代码为:

import tkinter as tk                    
from tkinter import ttk
from tkinter import *
from time import sleep
import time
import tkinter as tk
from tkinter import ttk

from selenium.webdriver import Firefox
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
import os

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 import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

from selenium.common.exceptions import ElementClickInterceptedException


root = tk.Tk()
root.title("...")
root.geometry('530x500')
root.configure(bg='white')

topbar = tk.Frame(root, bg='#3b589e', height=42, width = 660)
topbar.place(x=1, y=1)

secondbar = tk.Frame(root, bg='#f0f2f5', height=42, width = 660)
secondbar.place(x=1, y=40)

#GUI
label_email = Label(root, text="email", bg='#3b589e', foreground="white")
label_email.place(x=2, y=10)
email = tk.Entry(root)
email.place(x=50, y = 9)

label_password = Label(root, text="password", bg='#3b589e', foreground="white")
label_password.place(x=260, y = 10)
password = tk.Entry(root)
password.place(x=335, y = 9)

link_label = Label(root, text="Post Link", bg='#f0f2f5', foreground="black")
link_label.place(x=2, y = 52)
link = tk.Entry(root, width = 50)
link.place(x=97, y = 50)

link.insert(tk.END, "https://www.facebook.com/FranzKafkaAuthor/posts/4221775217885172")

number_requests_label = Label(root, text="How many requests to send?", bg='white', foreground="black")
number_requests_label.place(x=2, y = 110)
number_requests = tk.Entry(root)
number_requests.place(x=4, y = 130)
number_requests.insert(tk.END, "20")

time_label = Label(root, text="Seconds between requests?", bg='white', foreground="black")
time_label.place(x=2, y = 180)
time_requests = tk.Entry(root)
time_requests.place(x=4, y = 200)
time_requests.insert(tk.END, "1")

email.insert(tk.END, "example@example.it")
password.insert(tk.END, "example password")


def start_with_limits(): 
    # get the values from the textboxes and convert them to integers
    delay = int(time_requests.get())
    limit = int(number_requests.get())

    #Access Facebook
    profile_path = '/usr/bin/firefox/firefox'

    options=Options()
    options.set_preference('profile', profile_path)
    options.set_preference('network.proxy.type', 4)
    options.set_preference('network.proxy.socks', '127.0.0.1')
    options.set_preference('network.proxy.socks_port', 9050)
    options.set_preference("network.proxy.socks_remote_dns", False)

    service = Service('/home/xxxx/bin/geckodriver')
    driver = Firefox(service=service, options=options)
    driver.set_window_size(600, 990)
    driver.set_window_position(1, 1)
    driver.get("http://www.facebook.com")

    #Cookies before login
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-cookiebanner="accept_button"]'))).click()

    #Login
    username_box = driver.find_element(By.ID, 'email')
    username_box.send_keys(email.get())
    password_box = driver.find_element(By.ID, 'pass')
    password_box.send_keys(password.get())

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[1]/div[2]/div[1]/div/div/div/div[2]/div/div[1]/form/div[2]/button'))).click()

    # --OPTIONAL
    #Cookies before login (Sometimes it is required while sometimes not
    #WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[aria-label='Allow all cookies'] span span"))).click()


    #Open link
    driver.get(link.get())

    #Click on icon-like
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@class='j1lvzwm4']"))).click()
    time.sleep(1)

    #Click su ALL
    WebDriverWait(driver, 2000).until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[1]/div/div[1]/div/div[4]/div/div/div[1]/div/div[2]/div/div/div/div[1]/div/div/div/div/div[2]/div[2]'))).click()
    time.sleep(1)

    #Scroll down and press "Add friend" buttons
    wait = WebDriverWait(driver, 30)
    i = 1
    x = 1
    
    while i <= limit:
        i = i + 1

        try:
            row = wait.until(EC.visibility_of_element_located((By.XPATH, f"(//div[@data-visualcompletion='ignore-dynamic' and not (@role) and not (@class)])[{i}]")))
            add = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Add Friend']"))).click()
        
            driver.execute_script("arguments[0].scrollIntoView(true);", row)
            time.sleep(delay)



        except ElementClickInterceptedException:
            print("This button could not be clicked")

            close_popup = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Ok']"))).click()

            while True:
                x = x + 2
                row_skip = wait.until(EC.visibility_of_element_located((By.XPATH, f"(//div[@data-visualcompletion='ignore-dynamic' and not (@role) and not (@class)])[{x}]")))
                addd_skip = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Add Friend']"))).click()
                break

begin = Button(root, text="Start", bg='#3b589e', foreground='white', width=7, command= start_with_limits)
begin.place(x=1, y=420)

root.mainloop()

添加信息:“i”的主要目的是不跳过任何谱表,因此它必须滚动并计算每个谱表(所有谱表)。而“x”与“i”相比,必须跳过1个按钮(仅1个),但它必须跳过1次,然后只跳过1个按钮1次。随后,在异常跳转一个带“x”的按钮后,然后它 returns 到第一个 While ,点击所有按钮(不跳转任何按钮)直到找到新的异常。

XPATH IN ROW? 使用“行”中的 xpath,我选择了有按钮的每一行。行的名称都被称为相同的。准确地说,在你的屏幕上,你必须点击蓝色的图标,然后点击“全部”。我正在选择该部门的每一位员工。 P.S:(没有注意到我的浏览器使用了另一种语言,显然我会用英语的另一种浏览器进行测试)

P.S:我想指出,我的问题仅供个人和参考学习之用。我是 Python 的新手,现在正在学习 Selenium。我不想使用垃圾邮件,也不想在实际情况下使用脚本。尊重 Facebook 规则。正如我所说,我的问题只是一个好奇,出于个人学习的原因,以了解我这个好奇的代码。

您正在尝试发送给定数量的请求并以过于复杂的方式跳过错误的请求。这可能是最简单的方法:

  • 检查用户是否有“添加朋友”按钮
    • 如果是,请点击按钮
      • 如果出现错误框,关闭它,否则发送的请求数加1
  • 如果发送了所需数量的请求,则停止,否则转到下一个用户

.

requests_to_send = 20
requests_sent = 0
requests_failed = 0
i = 0 # number of users checked
users = []

while requests_sent < requests_to_send:
    
    # if necessary, wait until new users are loaded
    while i >= len(users):
        users = driver.find_elements(By.CSS_SELECTOR, 'div[aria-label=Reactions] div:nth-child(3) div[data-visualcompletion=ignore-dynamic]')
        time.sleep(.5)

    driver.execute_script('arguments[0].scrollIntoView({block: "center"});', users[i])
    button = users[i].find_elements(By.CSS_SELECTOR, 'div[aria-label="Add Friend"]')
    
    if button:
        button[0].click()
        time.sleep(2)
        cant_send = driver.find_elements(By.CSS_SELECTOR, 'div[aria-label=OK]')
        
        if cant_send:
            requests_failed += 1
            cant_send[0].click()
            # wait until popup is closed
            while driver.find_elements(By.CSS_SELECTOR, 'div[aria-label=OK]'):
                time.sleep(.5)
        else:
            requests_sent += 1
    
    i += 1
    print(f'users checked {i} - req. sent {requests_sent} - req. failed {requests_failed}', end='\r')

p.s。 fanne buono uso!