Как использовать getaddrinfo_a, чтобы сделать асинхронную твердость с glibc

Это сообщение об ошибке ...

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"button"}

... подразумевает, что ChromeDriver не смог найти нужный WebElement с помощью Стратегии локатора , которую вы использовали.

Соответствующий HTML-код помог бы нам лучше проанализировать вашу проблему. Однако вашей главной проблемой является несовместимость между версиями двоичных файлов, которые вы используете следующим образом:

  • Вы используете chromedriver = 2.25
  • [ 1135] Примечания к выпуску chromedriver = 2.25 ясно упоминают следующее:

Поддерживает Chrome v53-55

] blockquote>
  • Вы используете chrome = 70.0
  • Примечания к выпуску ChromeDriver v2.45 ясно упоминает следующее:

Поддерживает Chrome v70-72

blockquote>
  • Ваша версия Selenium Client является неизвестно нам.

Таким образом, существует явное несоответствие между ChromeDriver v2.25 и Chrome Browser v70.0

Решение

    [ 1139] Обновление Selenium до текущих уровней Версия 3.141.59 .
  • Обновите ChromeDriver до текущего уровня ChromeDriver v2.46 .
  • Сохранить версию Chrome между уровнями Chrome v71-73 . ( в соответствии с примечаниями к выпуску ChromeDriver v2.46 )
  • Очистите ваше рабочее пространство проекта через IDE и [1127 ] Перестройте ваш проект только с необходимыми зависимостями.
  • Если версия вашего основного веб-клиента устарела, удалите ее через Revo Uninstaller и установите последнюю версию GA и выпущенную версию Web Клиент . ​​
  • Выполните свой @Test.
  • Всегда вызывать метод driver.quit() в методе tearDown(){}, чтобы закрыть & amp; Изящно уничтожить экземпляры WebDriver и Web Client .

16
задан sztanpet 12 September 2008 в 01:07
поделиться

1 ответ

ОБНОВЛЕНИЕ (2010-10-11) : страницы справочника Linux теперь имеют документацию getaddrinfo_a, можно найти его здесь: http://www.kernel.org/doc/man-pages/online/pages/man3/getaddrinfo_a.3.html

Как правовая оговорка я должен добавить, что я довольно плохо знаком с C, но не точно новичком, таким образом, могли бы быть ошибки или плохо кодирование методов, исправьте меня (и моя грамматика сосет также).

я лично не знал об этом, пока я не натолкнулся это сообщение Adam Langley, я дам несколько фрагментов кода, чтобы проиллюстрировать использование его и разъяснить некоторые вещи, которые не могли бы быть что ясны на первом использовании. Преимущества использования этого - то, что Вы возвращаете данные, с готовностью применимые в [1 113], сокет () , слушают () и другие функции, и при правильной организации Вы не должны будете волноваться о ipv4/v6 также.
Так для начинаний с основами, как взято из ссылки выше (необходимо будет связаться против libanl (-lanl)):
Вот прототип функции:

int getaddrinfo_a(int mode, struct gaicb *list[], int ent, 
                  struct sigevent *);
  1. режимом является любой GAI_WAIT (который является, вероятно, не, что Вы хотите), и GAI_NOWAIT для асинхронных поисков
  2. , аргумент gaicb принимает массив хостов поиска с аргумент ent , указывающий, сколько элементов массив имеет
  3. , sigevent будет ответственен за сообщение функции, как мы должны быть уведомлены, больше на этом через мгновение

, А gaicb структура похож на это:

struct gaicb {
    const char *ar_name;
    const char *ar_service;
    const struct addrinfo *ar_request;
    struct addrinfo *ar_result;
};

, Если Вы знакомы с getaddrinfo, затем эти поля соответствуют им как так:

int getaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res);

узел является ar_name полем, сервис является портом, аргумент подсказок соответствует ar_request участнику, и результат хранится в остальных.
Теперь Вы указываете, как Вы хотите быть уведомленными через sigevent структуру:

struct sigevent {
    sigval_t sigev_value;
    int sigev_signo;
    int sigev_notify;
    void (*sigev_notify_function) (sigval_t);
    pthread_addr_t *sigev_notify_attributes;
};
  1. можно проигнорировать уведомление через установку _sigev_notify_ к SIGEV_NONE
  2. , можно инициировать сигнал через установку sigev_notify к SIGEV_SIGNAL и sigev_signo к полезному сигналу. Обратите внимание, что при использовании сигнала в реальном времени ( SIGRTMIN - SIGRTMAX, всегда используйте его через макросы и дополнение SIGRTMIN+2 и т.д.), можно провести указатель или значение в sigev_value.sival_ptr или sigev_value.sival_int участнике соответственно
  3. , можно запросить обратный вызов в новом потоке через установку sigev_notify к SIGEV_NONE

Так в основном, если Вы хотите искать имя хоста, Вы устанавливаете ar_name на хост и устанавливаете все остальное на [1 122] ПУСТОЙ УКАЗАТЕЛЬ , если Вы хотите соединиться с хостом, Вы устанавливаете ar_name и ar_service, и если Вы хотите создать сервер, Вы указываете ar_service и ar_result поле. Можно, конечно, настроить ar_request участника к содержанию основ, посмотреть человек getaddrinfo для большего количества информации

, Если у Вас есть цикл событий с select/poll/epoll/kqueue, Вы могли бы хотеть использовать signalfd для удобства. Signalfd создает дескриптор файла, на котором можно использовать обычные механизмы опроса события как так:

#define _GNU_SOURCE //yes this will not be so standardish
#include <netdb.h>
#include <signal.h>
#include <sys/signalfd.h>

void signalfd_setup(void) {
    int sfd;
    sigset_t mask;

    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN);
    sigprocmask(SIG_BLOCK, &mask, NULL); //we block the signal
    sfd = signalfd(-1, &mask, 0);
    //add it to the event queue
}
void signalfd_read(int fd) {
    ssize_t s;
    struct signalfd_siginfo fdsi;
    struct gaicb *host;

    while((s = read(fd, &fdsi, sizeof(struct signalfd_siginfo))) > 0){
    if (s != sizeof(struct signalfd_siginfo)) return; //thats bad
    host = fdsi.ssi_ptr; //the pointer passed to the sigevent structure
            //the result is in the host->ar_result member
            create_server(host);
    }
}
void create_server(struct gaicb *host) {
    struct addrinfo *rp, *result;
    int fd;

    result = host->ar_result;
    for(rp = result; rp != NULL; rp = rp->ai_next) {
        fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        bind(fd, rp->ai_addr, rp->ai_addrlen);
        listen(fd, SOMAXCONN);
        //error checks are missing!

        freeaddrinfo(host->ar_request);
        freeaddrinfo(result);
        //you should free everything you put into the gaicb
    }
}
int main(int argc, char *argv[]) {
    struct gaicb *host;
    struct addrinfo *hints;
    struct sigevent sig;

    host = calloc(1, sizeof(struct gaicb));
    hints = calloc(1, sizeof(struct addrinfo));

    hints->ai_family = AF_UNSPEC; //we dont care if its v4 or v6
    hints->ai_socktype = SOCK_STREAM;
    hints->ai_flags = AI_PASSIVE;
    //every other field is NULL-d by calloc

    host->ar_service = "8888"; //the port we will listen on
    host->ar_request = hints;

    sig.sigev_notify = SIGEV_SIGNAL;
    sig.sigev_value.sival_ptr = host;
    sig.sigev_signo = SIGRTMIN;

    getaddrinfo_a(GAI_NOWAIT, &host, 1, &sig);

    signalfd_setup();

    //start your event loop
    return 0;
}

можно, конечно, использовать простой обработчик сигналов для этого задания также, посмотреть человек sigaction для большего количества информации

17
ответ дан 30 November 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: