#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)