TypeError: 'NoneType' object is not iterable нет решения

def get_html (url, params= ""):
    r= requests.get (url, headers=HEADERS,params= params )
    return r 


def get_content(html):
    soup = BS(html, "html.parser")
    items= soup.find_all('div', class_='card')
    parser=[]
    for item in items: 
        parser.append (
            {
                "title": item.find('div', class_='card-header-text').find(class_="link").get_text(),
                "link": item.find('div', class_='card-header-text').find(class_="link").get("href"),
                "status": item.find('div', class_='card-header-wrap').find(class_="status").get_text(),
                "starting_date": item.find('div', class_='card-data-item__right-item').find(class_='data').get_text(),
                "desctiption": item.find('div', class_="block-lot-item__info info-item").get_text()
            }
        )
def save_doc(items, path):
   with open (path,"w",newline="", encoding="utf-8" ) as file:
        writer = csv.writer(file, delimiter=',')
        writer.writerow(['Название торгов','Ссылка', "Статус","Время начала торгов",'Описание'])
        for item in items:
            writer.writerow([item['title'],item['link'], item["status"],item["starting_date"],item['description']])

и вот в этом фрагменте выдает ошибку

def parse ():
    S= input("Параметры поиска")
    html=get_html(URL)
    if html.status_code == 200:
        parser=[]
        print(f'Запрос:{S}')
        html= get_html(URL, params ={'searchString': S})
        parser.extend(get_content(html.text))
        save_doc(parser,CSV)
        get_content(html.text)    
    else:
        print('Ошибка')

parse ()

и собственно ошибка

Traceback (most recent call last):
  File "___________", line 58, in <module>
    parse ()
  File "____________", line 49, in parse
    parser.extend(get_content(html.text))
TypeError: 'NoneType' object is not iterable

Ответы (1 шт):

Автор решения: n1tr0xs

Ваша функция get_content ничего не возвращает, т.е. возвращает None. Когда вы пишите parser.extend(get_content(html.text)) это всё равно что написать так:

for el in get_content(html.text):
    parser.append(el)

И вот на этом моменте появляется проблема: как вы хотите пробежать по None ? Чтобы это исправить достаточно добавить такую строку в конец функции get_content:

return parser

Я бы, кстати, заменил функцию get_content на генератор:

def get_content(html):
    soup = BS(html, "html.parser")
    items= soup.find_all('div', class_='card')
    for item in items: 
        yield {
            "title": item.find('div', class_='card-header-text').find(class_="link").get_text(),
            "link": item.find('div', class_='card-header-text').find(class_="link").get("href"),
            "status": item.find('div', class_='card-header-wrap').find(class_="status").get_text(),
            "starting_date": item.find('div', class_='card-data-item__right-item').find(class_='data').get_text(),
            "desctiption": item.find('div', class_="block-lot-item__info info-item").get_text()
        }

Еще функция get_html не соответсвует своему названию: она должна возвращать html-код страницы, а возвращает объект типа requests.Response.
Стоит или переименовать функцию (что намного проще и практичнее).
Или изменить ёё тело:

def get_html(url, params= ""):
    r = requests.get(url, headers=HEADERS, params=params)
    return r.text # <---

И теперь не нужно делать так:

html = get_html(URL, params ={'searchString': S})
parser.extend(get_content(html.text))

А достаточно написать так:

html = get_html(URL, params ={'searchString': S})
parser.extend(get_content(html))
→ Ссылка