Как избавиться от None при циклическом просмотре webelements?

#python #selenium #exception #web-scraping

#python #селен #исключение #очистка веб-страниц

Вопрос:

Я пытаюсь вернуть список веб-элементов без каких-либо None. Не уверен, почему, но, похоже pass , не работает. Есть идеи? пожалуйста.

Кстати. Это можно исправить с помощью Pandas, но я бы хотел придерживаться чистого Python / Selenium и понять, что не так.

 def get_(article):
    try:
        article.find_element_by_xpath(".//a[div[@class='accessible_elem']]")
    except NoSuchElementException:
        pass
    else:
        title = article.find_element_by_xpath(".//a[div[@class='accessible_elem']]").get_attribute('aria-label')
        pubdate = article.find_element_by_xpath(".//abbr").get_attribute('data-utime')
        url = article.find_element_by_xpath(".//a[div[@class='accessible_elem']]").get_attribute('href')
        return(title, pubdate, url)

output = []
for article in articles:
    content = get_(article)
    output.append(content)
 

введите описание изображения здесь

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

1. if title is None: pass , else … должно сработать. Обратите внимание, что статья может существовать, но иметь None значения для запрашиваемых вами атрибутов.

2. Критический элемент находится в try: statement . Остальное должно выполняться при значении True. Наверняка в некоторых статьях нет class=’accessible_elem’ .

Ответ №1:

Проблема: иногда ваш NoSuchElementException не попадает, потому что не возникает исключение NoSuchElementException. Одним из примеров является то, что элемент с class accessible_elem существует, но не имеет правильных атрибутов, которые вы считываете. Кроме того, когда вы проходите из-за исключения, функция возвращает None .

Исправление: это зависит, но вы, вероятно, захотите сначала проверить, нет ли содержимого, а затем, если какой-либо из title, pubdate или url не является None перед добавлением. Измените цикл for на:

 for article in articles:
  content = get_(article)
  if content and all([x is not None for x in content]):
    output.append(content)
 

Вы могли бы сократить проверку до:

 if content and all(content):
 

если бы вы знали, что вы никогда не получите значение 0 (ложное значение) для любого из значений кортежа.

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

1. Спасибо. Работает с небольшими изменениями: если содержимое не равно None:

2. Изменено, чтобы отразить это. Вероятно, вы хотите явно вернуть None из своего блока catch

3. Оба pass и return по неизвестной причине выдают None .

Ответ №2:

Вы использовали try-except-else структуру непреднамеренным образом.

Предложение использовать понимание списка:

 def analyze_article(article):
    try:
        article.find_element_by_xpath(".//a[div[@class='accessible_elem']]")
    except NoSuchElementException:
        return None
    
    # we know that the element must exist if we get to this point
    # if it did not, we returned None already and left the function body
    title = article.find_element_by_xpath(".//a[div[@class='accessible_elem']]").get_attribute('aria-label')
    pubdate = article.find_element_by_xpath(".//abbr").get_attribute('data-utime')
    url = article.find_element_by_xpath(".//a[div[@class='accessible_elem']]").get_attribute('href')
    return (title, pubdate, url)


# Get all items, be them None or not
items = [analyze_article(art) for art in articles]

# Filter out all None values
items = [item for item in items if item is not None]