Не могу понять что тут не так

Код:

import requests
from bs4 import BeautifulSoup

URL = 'https://auto.ru/schelkovo/cars/hyundai/used/'
HEADERS = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
    'accept': '*/*'}
HOST = 'https://auto.ru'


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


def get_content(html):
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_='ListingItem')

    cars = []
    for item in items:
        cars.append({
            'title': item.find('h3', class_='ListingItemTitle ListingItem_title').get_text(strip=True),
            'link': HOST + item.find('a', class_='Link ListingItemTitle_link').get('href'),
            'rub_price': item.find('div', class_='ListingItem_columnCellPrice').get_text(),
            'city': item.find('div', class_='ListingItem__additionalInfo').find_next('span').get_text(), })
    return cars


def parse():
    html = get_html(URL)
    if html.status_code == 200:
        cars = get_content(html.text)
    else:
        print('Error')

Ошибка:

Traceback (most recent call last):
  File "C:\Users\User\PycharmProjects\parse\main.py", line 38, in <module>
    parse()
  File "C:\Users\User\PycharmProjects\parse\main.py", line 33, in parse
    cars = get_content(html.text)
  File "C:\Users\User\PycharmProjects\parse\main.py", line 23, in get_content
    'title': item.find('h3', class_='ListingItemTitle ListingItem_title').get_text(strip=True),
AttributeError: 'NoneType' object has no attribute 'get_text'

Process finished with exit code 1

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

Автор решения: Сергей Шашко

В функций get_content переменная items принимает значенние пустой список

→ Ссылка
Автор решения: gil9red

Переписал код парсера

Основные различия:

  • Использование Session для запросов. Этот объект использует заголовки запроса, что ему укажешь, и можно дополнительно передавать через параметр headers=. Плюс, он помнит куки, что полезно
  • Для склеивания ссылок лучше использовать urljoin, а ссылку можно брать из ответа на запрос rs (если на сайте будет редирект, типа с http на https или на другой домен, то в rs.url будет актуальный адрес)
  • Использование css-селекторов в методах select и select_one. Они простые и повсеместно используются
  • Цену решил парсить как целое число, для тех машин, у которых цены нет, будет возвращено 0, но ничего не мешает возвращать None или что-то аналогичное

Пример:

from urllib.parse import urljoin

import requests
from bs4 import BeautifulSoup


def get_price(tag) -> int:
    try:
        # Оставляем только цифры
        value = ''.join(c for c in tag.get_text() if c.isdigit())
        return int(value)
    except:
        return 0


session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
session.headers['Accept'] = '*/*'


url = 'https://auto.ru/schelkovo/cars/hyundai/used/'

rs = session.get(url)
root = BeautifulSoup(rs.content, 'html.parser')

for item in root.select('.ListingItem'):
    title_el = item.select_one('.ListingItemTitle__link[href]')

    title = title_el.get_text(strip=True)
    url = urljoin(rs.url, title_el['href'])

    price_el = item.select_one('.ListingItemPrice__content')
    price = get_price(price_el)

    region_el = item.select_one('.MetroListPlace__regionName')
    city = region_el.get_text() if region_el else '-'

    print(f'{title!r}, {price}, {city!r}')
    print(url)
    print()

Результат:

'Hyundai Solaris I Рестайлинг', 810000, 'Тейково (180\xa0км от\xa0Щелково)'
https://auto.ru/cars/used/sale/hyundai/solaris/1105856012-839475dc/?geo_id=10765

'Hyundai Tucson IV', 3600000, 'Москва'
https://auto.ru/cars/used/sale/hyundai/tucson/1105942340-1686d5bc/?geo_id=10765

'Hyundai Grand Starex I Рестайлинг', 2385000, 'Москва'
https://auto.ru/cars/used/sale/hyundai/grand_starex/1105479054-60792926/?geo_id=10765

...

'Hyundai Sonata IV (EF) Рестайлинг', 245000, 'Москва'
https://auto.ru/cars/used/sale/hyundai/sonata/1105669699-a55923b6/?geo_id=10765

'Hyundai Elantra III (XD2) Рестайлинг', 289000, 'Москва'
https://auto.ru/cars/used/sale/hyundai/elantra/1105696908-ffede62d/?geo_id=10765
→ Ссылка