Программа возвращает исключение и завершается, даже если я использовал «Except — pass»

#python #python-3.x #selenium #selenium-webdriver #selenium-chromedriver

#python #python-3.x #селен #selenium-webdriver #selenium-chromedriver

Вопрос:

Я пишу программу webscraper, которая удаляет список ссылок из файла CSV. Проблема в том, что некоторые из посещаемых страниц пропускают часть информации, которую программа очищает, потому что компания их не предоставляет. Поэтому, если программа очищает телефонные номера и электронные письма, а затем номер телефона отсутствует, она возвращает исключение и завершается. Мне нужно, чтобы пропустить недостающий элемент и НЕ завершать программу, чтобы она могла очистить остальную информацию с недостающей информацией, представленной в виде пустого слота в файле CSV.

Это пример веб-страницы, которая содержит всю информацию и успешно очищает — [https://reality.idnes.cz/rk/detail/m-m-reality-holding-a-s/5a85b582a26e3a321d4f2700 /]

Это пример веб-страницы, на которой отсутствуют как адрес электронной почты, так и номер, а также причины и исключение, которое завершает работу программы — [https://reality.idnes.cz/rk/detail/narodni-realitni-holding-a-s/5a88aab9e88054474b0eca61 /]

Я попытался использовать «try — except (pass)», чтобы бороться с этим, чтобы пропустить исключение и продолжить выполнение программы, насколько я понимаю, но программа просто пропускает исключение все вместе и переходит к началу цикла и полностью пропускает информацию, которая не сохраняется в файле CSV.

Это мой код:

 from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.chrome.options import Options
import time
import csv

with open('links.csv') as read:
    reader = csv.reader(read)
    link_list = list(reader)
    with open('ScrapedContent.csv', 'w ', newline='') as write:
        writer = csv.writer(write)
        options = Options()
        options.add_argument('--no-sandbox')
        path = "/home/Projects/SRealityContentScraper/chromedriver"
        driver = webdriver.Chrome(path)
        wait = WebDriverWait(driver, 10)
        for link in link_list:
            driver.get(', '.join(link))
            time.sleep(2)
            information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "h1.b-annot__title.mb-5")))
            title = driver.find_element_by_css_selector("h1.b-annot__title.mb-5")
            information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "span.btn__text")))
            offers = driver.find_element_by_css_selector("span.btn__text")
            information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "p.font-sm")))
            addresses = driver.find_element_by_css_selector("p.font-sm")
            try:
                information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "a.item-icon.measuring-data-layer")))
                phone_number = driver.find_element_by_css_selector("a.item-icon.measuring-data-layer")
            except Exception:
                pass
            try:
                information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "a.item-icon")))
                email = driver.find_element_by_css_selector("a.item-icon")
            except Exception:
                pass
            print(title.text, " ", offers.text, " ", addresses.text, " ", phone_number.text, " ", email.text)
            writer.writerow([title.text, offers.text, addresses.text, phone_number.text, email.text])

        driver.quit()
  

Насколько я понимаю, «except — continue» должен повторять цикл с самого начала, а «except — pass» должен просто игнорировать исключение и продолжать нормально запускать программу, чего не происходит. Как я могу предотвратить потерю данных, чтобы сохранить информацию и исключить недостающую информацию? Спасибо за любую помощь в этом, я пытался разобраться в этом уже несколько часов!

Комментарии:

1. Что такое исключение и в какой строке оно возникает? Может ли быть так, что ваше исключение выдается за пределы вашей попытки?

2. Я вижу, что последние строки в вашем цикле обращаются к email.text и phone_number.text, даже если они не были созданы, если цикл не удался…. Это ваше исключение?

3. Я опубликую ответ для вас — дайте мне несколько минут 🙂

Ответ №1:

Как упоминалось в комментариях, ваша проблема заключается в том, что ваши элементы определены в операторе try.

Когда попытка завершается неудачно, они не создаются, и далее в цикле вы не можете получить доступ к .text .

В качестве примера посмотрите на этот простой код, в котором объект всегда будет терпеть неудачу:

 driver.get("http://www.google.com")
try:
    someElement = driver.find_element_by_name('I will Fail!')
except Exception:
    pass
print (someElement.text)
  

Это выдает эту ошибку при печати:

Произошло исключение: ошибка имени ‘someElement’ не определено

Одним из решений является создание строковой переменной перед попыткой — установите для нее значение blank или любое другое значение по умолчанию, которое вы хотите. При попытке установите для этого значение text из элемента. Если он не может быть найден, попытка завершается, а текстовое значение остается по умолчанию.

Приведенный выше код становится таким:

 someElement_Text = "" # use a string like "" or "none" or "blank" or "not found"
try:
    someElement = driver.find_element_by_name('I will Fail!')
    someElement_Text = someElement.text
except Exception:
    pass
print (someElement_Text)
  

Этот код не выдает ошибку.

Вы захотите изменить вторую половину своего цикла на это:

             phone_number_text = ""
            try:
                information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "a.item-icon.measuring-data-layer")))
                phone_number = driver.find_element_by_css_selector("a.item-icon.measuring-data-layer")
                phone_number_text = phone_number.text
            except Exception:
                pass

            email_text = ""
            try:
                information_list = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "a.item-icon")))
                email = driver.find_element_by_css_selector("a.item-icon")
                email_text = email.text
            except Exception:
                pass
            print(title.text, " ", offers.text, " ", addresses.text, " ", phone_number_text, " ", email_text)
            writer.writerow([title.text, offers.text, addresses.text, phone_number_text, email_text])

  

Комментарии:

1. Я хотел написать команду, объясняющую, как я исправил проблему, но Stack Overflow не позволил мне обновить ее через 5 минут после ее публикации… Предлагаемые шаги были первым, что я попробовал, и это сработало бы, но метод .text не может работать со строкой. Для этого я создал еще один цикл try, который присваивает email = email.text, и если возникает исключение email = » «, то writerow и print получают исходное значение email, несмотря ни на что. Спасибо за помощь. Последний пользователь не отправил его в качестве ответа, поэтому я отмечаю это как решение.