Два ответа
1. Ответьте на заданный вопрос.
2. Простое изменение равно лучшему пути!
Ответ 1 - Передайте массив Vars в __construct () в классе, вы также можете оставить конструкцию пустой и передать массивы через ваши функции.
<?php
// Create an Array with all needed Sub Arrays Example:
// Example Sub Array 1
$content_arrays["modals"]= array();
// Example Sub Array 2
$content_arrays["js_custom"] = array();
// Create a Class
class Array_Pushing_Example_1 {
// Public to access outside of class
public $content_arrays;
// Needed in the class only
private $push_value_1;
private $push_value_2;
private $push_value_3;
private $push_value_4;
private $values;
private $external_values;
// Primary Contents Array as Parameter in __construct
public function __construct($content_arrays){
// Declare it
$this->content_arrays = $content_arrays;
}
// Push Values from in the Array using Public Function
public function array_push_1(){
// Values
$this->push_values_1 = array(1,"2B or not 2B",3,"42",5);
$this->push_values_2 = array("a","b","c");
// Loop Values and Push Values to Sub Array
foreach($this->push_values_1 as $this->values){
$this->content_arrays["js_custom"][] = $this->values;
}
// Loop Values and Push Values to Sub Array
foreach($this->push_values_2 as $this->values){
$this->content_arrays["modals"][] = $this->values;
}
// Return Primary Array with New Values
return $this->content_arrays;
}
// GET Push Values External to the Class with Public Function
public function array_push_2($external_values){
$this->push_values_3 = $external_values["values_1"];
$this->push_values_4 = $external_values["values_2"];
// Loop Values and Push Values to Sub Array
foreach($this->push_values_3 as $this->values){
$this->content_arrays["js_custom"][] = $this->values;
}
// Loop Values and Push Values to Sub Array
foreach($this->push_values_4 as $this->values){
$this->content_arrays["modals"][] = $this->values;
}
// Return Primary Array with New Values
return $this->content_arrays;
}
}
// Start the Class with the Contents Array as a Parameter
$content_arrays = new Array_Pushing_Example_1($content_arrays);
// Push Internal Values to the Arrays
$content_arrays->content_arrays = $content_arrays->array_push_1();
// Push External Values to the Arrays
$external_values = array();
$external_values["values_1"] = array("car","house","bike","glass");
$external_values["values_2"] = array("FOO","foo");
$content_arrays->content_arrays = $content_arrays->array_push_2($external_values);
// The Output
echo "Array Custom Content Results 1";
echo "<br>";
echo "<br>";
echo "Modals - Count: ".count($content_arrays->content_arrays["modals"]);
echo "<br>";
echo "-------------------";
echo "<br>";
// Get Modals Array Results
foreach($content_arrays->content_arrays["modals"] as $modals){
echo $modals;
echo "<br>";
}
echo "<br>";
echo "JS Custom - Count: ".count($content_arrays->content_arrays["js_custom"]);
echo "<br>";
echo "-------------------";
echo "<br>";
// Get JS Custom Array Results
foreach($content_arrays->content_arrays["js_custom"] as $js_custom){
echo $js_custom;
echo "<br>";
}
echo "<br>";
?>
Ответ 2 - Простые изменения, однако, поставили бы его в соответствие с современными стандартами. Просто объявите свои массивы в классе.
<?php
// Create a Class
class Array_Pushing_Example_2 {
// Public to access outside of class
public $content_arrays;
// Needed in the class only
private $push_value_1;
private $push_value_2;
private $push_value_3;
private $push_value_4;
private $values;
private $external_values;
// Declare Contents Array and Sub Arrays in __construct
public function __construct(){
// Declare them
$this->content_arrays["modals"] = array();
$this->content_arrays["js_custom"] = array();
}
// Push Values from in the Array using Public Function
public function array_push_1(){
// Values
$this->push_values_1 = array(1,"2B or not 2B",3,"42",5);
$this->push_values_2 = array("a","b","c");
// Loop Values and Push Values to Sub Array
foreach($this->push_values_1 as $this->values){
$this->content_arrays["js_custom"][] = $this->values;
}
// Loop Values and Push Values to Sub Array
foreach($this->push_values_2 as $this->values){
$this->content_arrays["modals"][] = $this->values;
}
// Return Primary Array with New Values
return $this->content_arrays;
}
// GET Push Values External to the Class with Public Function
public function array_push_2($external_values){
$this->push_values_3 = $external_values["values_1"];
$this->push_values_4 = $external_values["values_2"];
// Loop Values and Push Values to Sub Array
foreach($this->push_values_3 as $this->values){
$this->content_arrays["js_custom"][] = $this->values;
}
// Loop Values and Push Values to Sub Array
foreach($this->push_values_4 as $this->values){
$this->content_arrays["modals"][] = $this->values;
}
// Return Primary Array with New Values
return $this->content_arrays;
}
}
// Start the Class without the Contents Array as a Parameter
$content_arrays = new Array_Pushing_Example_2();
// Push Internal Values to the Arrays
$content_arrays->content_arrays = $content_arrays->array_push_1();
// Push External Values to the Arrays
$external_values = array();
$external_values["values_1"] = array("car","house","bike","glass");
$external_values["values_2"] = array("FOO","foo");
$content_arrays->content_arrays = $content_arrays->array_push_2($external_values);
// The Output
echo "Array Custom Content Results 1";
echo "<br>";
echo "<br>";
echo "Modals - Count: ".count($content_arrays->content_arrays["modals"]);
echo "<br>";
echo "-------------------";
echo "<br>";
// Get Modals Array Results
foreach($content_arrays->content_arrays["modals"] as $modals){
echo $modals;
echo "<br>";
}
echo "<br>";
echo "JS Custom - Count: ".count($content_arrays->content_arrays["js_custom"]);
echo "<br>";
echo "-------------------";
echo "<br>";
// Get JS Custom Array Results
foreach($content_arrays->content_arrays["js_custom"] as $js_custom){
echo $js_custom;
echo "<br>";
}
echo "<br>";
?>
Оба параметра выдают одну и ту же информацию и позволяют функции выводить и извлекать информацию из массива и вспомогательных массивов в любое место в коде (учитывая, что данные был выдвинут первым). Второй вариант дает больше контроля над тем, как данные используются и защищены. Они могут использоваться так, как они просто изменяются до ваших потребностей, но если они используются для расширения контроллера, они могут делиться своими значениями между любыми классами, которые использует контроллер.
Выход:
Результаты пользовательского контента Array
Модалы - количество: 5
] a
b
c
FOO
foo
JS Custom - Count: 9
1
2B или нет 2B
3
42
5
автомобиль
g20]дом
мотоцикл
стекло
Вместо того, чтобы использовать login.send_keys(Keys.ENTER)
, вы должны использовать метод селена click()
, который будет работать для вас.
Сначала вы можете проверить, активен ли элемент, а затем нажать на него. Нравится:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()
Для безголового браузера Chrome вам необходимо указать размер окна, а также в параметрах Chrome. Для безголового браузера селен не может определить размер вашего окна. Попробуйте и сообщите мне.
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('window-size=1920x1480')
Это сообщение об ошибке ...
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
... подразумевает, что нужный элемент не был интерактивным , когда вы пытались вызвать click()
для него.
Пара фактов:
Я использовал тот же xpath , который вы построили, и вы можете использовать следующее решение:
Кодовый блок:
[111 ]Снимок браузера:
Похоже, у вас возникла проблема с XPATH, когда вы обнаружили, что кнопка «Отправить» или ваша кнопка «Отправить» недоступна, или к вашей кнопке «Отправить» прикреплены некоторые события на стороне клиента (javascript / etc ), которые необходимы для эффективной отправки страницы.
Вызов метода pw.submit () в большинстве случаев должен избавить от необходимости ждать, пока кнопка отправки станет кликабельной, и избежать проблем с поиском кнопки в большинстве случаев. На многих других веб-сайтах некоторые из необходимых внутренних процессов запускаются действиями на стороне клиента, которые выполняются после того, как кнопка «отправить» фактически нажата (хотя для примечания это не считается наилучшей практикой, поскольку сайт менее доступен и т. д., я отвлекся). Прежде всего, важно следить за выполнением вашего скрипта и следить за тем, чтобы на веб-странице не отображалось никаких заметных ошибок в отношении учетных данных, которые вы отправляете.
Кроме того, однако, некоторые веб-сайты требуют добавления определенного минимального промежутка времени между вводом имени пользователя, пароля и отправкой страницы, чтобы она считалась действительным процессом отправки. Я даже заходил на веб-сайты, которые требуют от вас использовать send_keys 1 для имен пользователей и паролей, чтобы избежать использования некоторых технологий защиты от взлома. В этих случаях я обычно использую следующее между вызовами:
from random import random, randint
def sleepyTime(first=5, second=10):
# returns the value of the time slept (as float)
# sleeps a random amount of time between the number variable in first
# and the number variable second (in seconds)
sleepy_time = round(random() * randint(first, second), 2)
sleepy_time = sleepy_time if sleepy_time > first else (first + random())
sleep(sleepy_time)
return sleepy_time
Я не вижу, что вы используете для того, чтобы сделать переменные _email и _password глобальными, если только они не изменяются где-то в функции входа в систему и вы хотите, чтобы это изменение было перенесено на другие сферы.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, TimeoutException
TIME_TIMEOUT = 20 # Twenty-second timeout default
def eprint(*args, **kwargs):
""" Prints an error message to the user in the console (prints to sys.stderr), passes
all provided args and kwargs along to the function as usual. Be aware that the 'file' argument
to print can be overridden if supplied again in kwargs.
"""
print(*args, file=sys.stderr, **kwargs)
def login(driver):
global _email, _password
try:
email = WebDriverWait(driver, TIME_TIMEOUT).until(EC.presence_of_element_located((By.XPATH, "//input[@id='user_email']")))
pw = WebDriverWait(driver, TIME_TIMEOUT).until(EC.presence_of_element_located((By.XPATH, "//input[@id='password']"))
pw.submit()
# if this doesn't work try the following:
# btn_submit = WebDriverWait(driver, TIME_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//button[@track-element='click-for-login']"))
# btn_submit.click()
# if that doesn't work, try to add some random wait times using the
# sleepyTime() example from above to add some artificial waiting to your email entry, your password entry, and the attempt to submit the form.
except NoSuchElementException as ex:
eprint(ex.msg())
except TimeoutException as toex:
eprint(toex.msg)
if __name__ == '__main__':
driver = webdriver.Chrome('/usr/bin/chromium/chromedriver',chrome_options=chrome_options)
#d.get('https://www.google.nl/')
#driver = webdriver.Chrome()
driver.maximize_window()
driver.get('https://www.goeventz.com/')
if login(driver) is not None:
print(create_event(driver))