“While”循环中的问题:带有 Selenium 的页面列表不会向下滚动

问题描述 投票:0回答:1

出于个人学习目的,我正在创建这个简短的脚本,目的是打开指向 Facebook 帖子的链接,并在滚动条滚动列表时单击所有“添加朋友”按钮。为了避免垃圾邮件,我添加了选择最大添加人数和请求间隔时间的功能。

我有可执行和完整的代码(在问题的最后发布),但是有问题。我如何向下滚动列表并同时单击与设置相关的“添加朋友”按钮以选择要添加的最大人数以及一个请求与另一个请求之间的时间?

(正确向下滚动) 如果我像这样写,那么滚动条就会向下滚动

i = 1

while True:
i = i + 1

row = wait.until(EC.visibility_of_element_located((By.XPATH, f"(//div[@data-visualcompletion='ignore-dynamic' and not (@role) and not (@class)])[{i}]")))

driver.execute_script("arguments[0].scrollIntoView(true);", row)

(未正确向下滚动) 例如,如果我添加五线谱以单击所有按钮,则滚动条不再下降(仅自动单击第一个“添加朋友”按钮,因此您不会点击下面的,我也想点击下面的按钮)

wait = WebDriverWait(driver, 30)
i = 1

while True:
i = i + 1

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()
close_popup = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Ok']"))).click()

driver.execute_script("arguments[0].scrollIntoView(true);", row, add, close_popup)

这是完整代码:

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

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/3985338151528881") #example link

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, "10")

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


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/xxx/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

    while i <= limit:
        i = i + 1

        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()
        close_popup = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Ok']"))).click()
        
        driver.execute_script("arguments[0].scrollIntoView(true);", row, add, close_popup)
        time.sleep(delay)


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

root.mainloop()
python python-3.x selenium selenium-webdriver scrollbar
1个回答
0
投票

Selenium 有一个有趣的特性: 如果你需要在页面底部做一些事情,例如,点击一个按钮,你不需要告诉它滚动,它会自动完成。 可能我没看懂你的意思,但是如果你需要滚动,我的建议是直接告诉它做页面底部的操作即可。

© www.soinside.com 2019 - 2024. All rights reserved.