Объект «Нетип» не может быть подписан при создании заголовка изображения на веб-сайте

#python #web-scraping

Вопрос:

 url2 = 'https://www.newegg.ca/Desktop-Graphics-Cards/SubCategory/ID-48?Tid=7708'

# opening up connection, grabbing page
uclient = ureq(url2)
html = uclient.read()
uclient.close()


# html parsing
page_soup = soup(html, "html.parser")

#grabs each product
containers = page_soup.findAll("div",{"class":"item-container"})

print(containers[0].div.div.a.img["title"])

for container in containers:
    brand = container.div.div.a.img["title"]
    title_container = container.findAll("a", {"class":"item-title"})
    product_name = title_container[0].text
    shipping_container = container.findAll("li", {"class":"price-ship"})
    shipping = shipping_container[0].text.strip()
    print(brand)
    print(product_name)
    print(shipping)
 

Проблема возникает во время цикла for brand = container.div.div.a.img["title"]
Это дает мне ошибку, что объект «Нетип» не может быть подписан. Странно то, что я могу получить доступ к этому заголовку и даже распечатать его вне цикла print(containers[0].div.div.a.img["title"]) , Пожалуйста, помогите мне понять, что здесь происходит. Спасибо, всего наилучшего!

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

1. Не выполнив код, я предполагаю, что эта проблема возникает с элементом, отличным от нулевого, другими словами containers[i] , для i != 0 . Проверьте, действительно ли все элементы containers имеют «структуру» div.div.a.img["title"] .

2. На какой итерации цикла возникает эта ошибка?

3. Я привык for number, container in enumerate(containers): print('---', number, '---') ... видеть, какая итерация создает проблему, и это дает мне ошибку containers[15] . Вы должны использовать if/else , чтобы проверить container.div.div.a.img , дает ли None и пропустить этот элемент.

Ответ №1:

С помощью

 for number, container in enumerate(containers):  
    print("---", number, "---") 
    # ... code ...
 

Я обнаружил, что это создает проблемы только для containers[15] .

Вы должны использовать if/else , чтобы проверить, container.div.div.a.img дает None ли и пропускает ли этот элемент, или установить текст по умолчанию.

     if container.div.div.a.img:
        brand = container.div.div.a.img["title"]
    else:
        brand = "???"
 

Полный рабочий код

 from bs4 import BeautifulSoup as soup
from urllib.request import urlopen as ureq

url2 = 'https://www.newegg.ca/Desktop-Graphics-Cards/SubCategory/ID-48?Tid=7708'

# opening up connection, grabbing page
uclient = ureq(url2)
html = uclient.read()
uclient.close()

# html parsing
page_soup = soup(html, "html.parser")

#grabs each product
containers = page_soup.findAll("div", {"class":"item-container"})

#print(containers[15].div.div.a.img["title"])

for number, container in enumerate(containers):
    print("---", number, "---")

    if container.div.div.a.img:
        brand = container.div.div.a.img["title"]
    else:
        brand = "???"

    title_container = container.findAll("a", {"class": "item-title"})
    product_name = title_container[0].text

    shipping_container = container.findAll("li", {"class": "price-ship"})
    shipping = shipping_container[0].text.strip()

    print(brand)
    print(product_name)
    print(shipping)
 

Редактировать:

Я проверяю веб-страницу, чтобы увидеть это containers[15] , и на ней есть дополнительный div текст #1 BEST SELLER , и это создает проблему. Для этого нужен другой метод — т. е.

     brand = container.div.find("img", {"title": True})["title"]
 

Вы можете использовать его даже со всеми контейнерами

 for number, container in enumerate(containers):
    print("---", number, "---")

    #if container.div.div.a.img:
    #    brand = container.div.div.a.img["title"]
    #else:
    #    brand = "???"
        
    brand = container.div.find('img', {"title": True})["title"]
        
    product_name = container.find("a", {"class": "item-title"}).text
    shipping = container.find("li", {"class": "price-ship"}).text.strip()

    print(brand)
    print(product_name)
    print(shipping)