Как закрыть popover-форму с помощью python selenium? - PullRequest
0 голосов
/ 21 декабря 2018

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

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

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

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

# 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)

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

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

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

driver.switch_to.alert 

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

Чтовы видите, что на самом деле это 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()
0 голосов
/ 21 декабря 2018

Если это фактическое предупреждение, это должно работать для вас.Для справки, , вот соответствующий раздел документации 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]
...