Как закрыть popover-форму с помощью селена Python?

С сайта Indeed.com я пытаюсь автоматически получить названия должностей, работодателей и описания.

Работает нормально, пока цикл не попадет на вторую страницу.

Появляется всплывающая форма, в которой я должен нажать «Nein, danke». Кнопка, чтобы продолжить. Когда появляется этот altert, цикл просто останавливается.

Мой код выглядит так и отлично работает до второй страницы:

# Import the packages
from selenium import webdriver
from time import sleep
import nltk
from nltk.tokenize import word_tokenize
import numpy as np
import pandas as pd
import gensim

# Start Webscraping
driver = webdriver.Safari()
driver.maximize_window()

# List with indeed URLs to scrape through
indeed_url_list = ['https://de.indeed.com/Jobs?q=data&l=&sort=date',
                   'https://de.indeed.com/jobs?q=Data&sort=date&start=10',
                   'https://de.indeed.com/jobs?q=Data&sort=date&start=20',
                   'https://de.indeed.com/jobs?q=Data&sort=date&start=30',
                   'https://de.indeed.com/jobs?q=Data&sort=date&start=40'
                   ]

# Empty lists that will be filled
indeed_job_links = []         # list with links to scrape through
indeed_job_titles = []        # list with job titles
indeed_job_employers = []     # list with job employers
indeed_job_descriptions = []  # list with job descriptions

# for loop for scraping
for indeed_page in indeed_url_list:    
    driver.get(indeed_page)    
    links = driver.find_elements_by_xpath('//div[@class = "jobsearch-SerpJobCard row result clickcard" or @class = "jobsearch-SerpJobCard row sjlast result clickcard" or @class = "jobsearch-SerpJobCard row result clickcard vjs-highlight" or @class = "jobsearch-SerpJobCard lastRow row result clickcard" or @class = "jobsearch-SerpJobCard row result clickcard vjs-highlight"]/*/a')     

    # get job link to list
    for i in list(links):
        indeed_job_links.append(i.get_attribute('href'))

    # scrape through the job descriptions
    for link in links:
        # open the link
        link.click()
        sleep(0.6)
        # get job title to list
        indeed_title = driver.find_element_by_xpath('//div[@id = "vjs-jobtitle"]').text
        indeed_job_titles.append(indeed_title)
        # get job employer to list
        indeed_employer = driver.find_element_by_xpath('//span[@id = "vjs-cn"]').text
        indeed_job_employers.append(indeed_employer)
        # get job description to list
        indeed_description = ' '.join(word_tokenize(driver.find_element_by_xpath('//div[@id = "vjs-desc"]').text))
        indeed_job_descriptions.append(indeed_description)

Я действительно не знаю, что здесь делать. Есть у кого-нибудь идеи? Большое Вам спасибо.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
547
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если это настоящее предупреждение, это должно сработать для вас. Для справки: вот соответствующий раздел документации Selenium

alertObj = driver.switch_to.alert
alertObj.accept()
alertObj.dismiss()

Я часто сталкиваюсь с предупреждениями при тестировании наших приложений. Я обнаружил, что они могут быть весьма ненадежными в зависимости от того, сколько времени требуется веб-странице для их отображения. Вот моя стандартная реализация.

def test(self):
    self.driver.find_element_by_name(a).clear()
    self.driver.find_element_by_name(b).send_keys()
    self.driver.find_element_by_name(c).click()

    # wait for an alert box to render
    time.sleep(1)

    try:
        alert_text = self.driver.switch_to.alert
        self.assertEqual('alert text', alert_text.text)
        self.driver.switch_to.alert.dismiss()
    except TypeError:
        [do stuff]

Может быть, это не оповещение, а всплывающее окно. Важно то, что оно появляется внезапно и обычно мне приходится нажимать «Nein, danke». Кнопка, чтобы двигаться дальше. Так что моя петля просто останавливается. Может ли ваш код сделать именно это?

Larsus123 21.12.2018 18:00

Я посмотрел на всплывающее окно, на которое вы ссылались на Indeed.com. Это диалоговое окно, а не предупреждение браузера, поэтому предыдущий ответ, в котором вы переключаетесь на предупреждение, не сработает.

driver.switch_to.alert 

будет работать только в случае предупреждений JavaScript.

То, что вы видите на сайте Indeed.com, представляет собой диалоговое окно HTML, и его следует обрабатывать так же, как и любые другие элементы страницы.

В самый первый раз, когда вы меняете страницу, вы знаете, что это диалоговое окно появится, поэтому дождитесь его и закройте. Я не уверен, появится ли он снова после того, как вы измените количество страниц N. Но если это так, вместо того, чтобы закрыть его, вы можете подумать о том, чтобы отправить ему электронное письмо, чтобы оно не появлялось. Или каждый раз, когда вы меняете страницу, вы можете проверять, отображается ли диалог, и закрывать его - это менее оптимально.

Вот ваш код, слегка подправленный с поддержкой закрытия диалогового окна:

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


class IndeedScraper:

    # List with indeed URLs to scrape through
    INDEED_URL_LIST = ['https://de.indeed.com/Jobs?q=data&l=&sort=date',
                       'https://de.indeed.com/jobs?q=Data&sort=date&start=10',
                       'https://de.indeed.com/jobs?q=Data&sort=date&start=20',
                       'https://de.indeed.com/jobs?q=Data&sort=date&start=30',
                       'https://de.indeed.com/jobs?q=Data&sort=date&start=40'
                       ]

    # Empty lists that will be filled
    INDEED_JOB_LINKS = []         # list with links to scrape through
    INDEED_JOB_TITLES = []        # list with job titles
    INDEED_JOB_EMPLOYERS = []     # list with job employers
    INDEED_JOB_DESCRIPTIONS = []  # list with job descriptions

    def __init__(self, driver):

        self.driver = driver
        self.have_closed_dialog = False

    def scrape(self):

        for indeed_page in IndeedScraper.INDEED_URL_LIST:
            self.driver.get(indeed_page)
            links = self.driver.find_elements_by_xpath(
                '//div[@class = "jobsearch-SerpJobCard row result clickcard" or '
                '@class = "jobsearch-SerpJobCard row sjlast result clickcard" or '
                '@class = "jobsearch-SerpJobCard row result clickcard vjs-highlight" or '
                '@class = "jobsearch-SerpJobCard lastRow row result clickcard" or '
                '@class = "jobsearch-SerpJobCard row result clickcard vjs-highlight"]/*/a')

            # get job link to list
            for i in list(links):
                IndeedScraper.INDEED_JOB_LINKS.append(i.get_attribute('href'))

            # scrape through the job descriptions
            for link in links:
                # open the link
                link.click()
                sleep(0.6)
                self.__close_dialog()  # Will close the dialog once and only if its shown
                self.__get_job_titles()
                self.__get_job_employers()
                self.__get_job_descriptions()

    def __is_dialog_shown(self):
        try:
            WebDriverWait(self.driver, 0.3).until(EC.presence_of_element_located((By.ID, "popover-foreground")))
            return True
        except:
            return False

    def __close_dialog(self):

        if not self.have_closed_dialog and self.__is_dialog_shown():
            self.driver.find_element(By.ID, "popover-link-x").click()
            self.have_closed_dialog = True
        return self

    def __get_job_titles(self):
        # get job title to list
        IndeedScraper.INDEED_JOB_TITLES.append(self.driver.find_element_by_xpath('//div[@id = "vjs-jobtitle"]').text)
        return self

    def __get_job_employers(self):
        # get job employer to list
        IndeedScraper.INDEED_JOB_EMPLOYERS.append(self.driver.find_element_by_xpath('//span[@id = "vjs-cn"]').text)
        return self

    def __get_job_descriptions(self):
        # get job description to list
        description = ' '.join(word_tokenize(self.driver.find_element_by_xpath('//div[@id = "vjs-desc"]').text))
        IndeedScraper.INDEED_JOB_DESCRIPTIONS.append(description)
        return self


if "__main__" == __name__:

    driver = webdriver.Safari()
    driver.maximize_window()
    scraper = IndeedScraper(driver)
    scraper.scrape()

Спасибо, Артур, и прошу прощения за поздний ответ. Я внезапно застрял в новом проекте, но теперь у меня есть время заняться поиском в Интернете. Я опробую вашу идею. Большое спасибо.

Larsus123 26.03.2019 12:10

Другие вопросы по теме

403 запрещено на селене при посещении страницы, которая работает в обычном браузере
Можно ли включить Xvfb в декларативном конвейере Jenkins для выполнения автономных тестов Selenium
При парсинге веб-страниц с использованием Python Selenium возвращаются неверные значения
При загрузке профиля на запуск тестов Selenium требуется несколько минут
Python Selenium не может войти в систему, нажав кнопку внутри формы
Selenium.common.exceptions.WebDriverException не было обработано кодом пользователя и ошибкой HTTP 400. Имя хоста запроса недействительно с Selenium
Использование селена в Python для поиска адресов электронной почты и возврата информации не удается, если нет результата
Создана автоматизированная среда тестирования, работающая с использованием Firefox. Получение некоторых ошибок при запуске тестов, хотя все тесты работают нормально
Как очистить данные, которые имеют математические обозначения html, и получить их точно в текстовом формате?
В каких случаях лучше выбрать Katalon вместо Selenium?