#python #web-scraping #beautifulsoup
#python #очистка веб-страниц #beautifulsoup
Вопрос:
После просмотра видео я попытался получить цену за товар с Amazon.веб-сайт с использованием API BeautifulSoup.
#My CODE
import requests
from bs4 import BeautifulSoup
URL = 'https://www.amazon.de/Neues-Apple-iPhone-Pro-128-GB/dp/B08L5SNWD2/ref=sr_1_1_sspa?__mk_de_DE=ÅMÅŽÕÑamp;crid=3UH87RWLLO40Eamp;dchild=1amp;keywords=iphone 12 proamp;qid=1605603669amp;sprefix=Iphone 12,aps,175amp;sr=8-1-sponsamp;psc=1amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzRjAxN0xWNTk0TVpYJmVuY3J5cHRlZElkPUEwNzE4ODIxMktCWlhJMVlHWDFNMyZlbmNyeXB0ZWRBZElkPUExMDMwODk2Tk5OVkdZRTJISDVMJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ=='
headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
page = requests.get(URL, headers=headers)
soup = BeautifulSoup(page.content, 'lxml')
#I tried other parsing methods too: 'html.parser', 'html5lib'. Not helpful
title = soup.find(id="productTitle").get_text()
price = soup.find(id='priceblock_ourprice')
print(title) #returns correct string from the URL above
print(price)
#returns 'None'. Unexpected. Expecting price with some extensions from <span id="priceblock_ourprice"
Любой, кто найдет что-то неправильное в моем коде, был бы мне очень полезен.
Заранее спасибо!
Комментарии:
1. элемент, который вы пытаетесь найти, динамически генерируется с помощью javascript.
requests.get
возвращает только исходный HTML-код (который вы можете просмотреть, добавив aview-source:
перед URL-адресом в вашем браузере). На этой исходной странице нет элемента, который вы ищете2. о каком элементе вы упоминаете? Можете ли вы объяснить более подробно?
3. перейдите по этому URL-адресу, щелкните правой кнопкой мыши на странице, выберите просмотр источника, попробуйте найти элемент с идентификатором
priceblock_ourprice
4. <класс td «a-span12» > <span> Я вижу это в элементе
5. Вы уверены, что проверяете исходную страницу? не страница элемента проверки?
Ответ №1:
Не удается воспроизвести ‘None’, код работает нормально, просто добавлен get_text()
к цене и strip()
обеим переменным, чтобы сделать результат немного чище.
import requests, time
from bs4 import BeautifulSoup
URL = 'https://www.amazon.de/Neues-Apple-iPhone-Pro-128-GB/dp/B08L5SNWD2/ref=sr_1_1_sspa?__mk_de_DE=ÅMÅŽÕÑamp;crid=3UH87RWLLO40Eamp;dchild=1amp;keywords=iphone 12 proamp;qid=1605603669amp;sprefix=Iphone 12,aps,175amp;sr=8-1-sponsamp;psc=1amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzRjAxN0xWNTk0TVpYJmVuY3J5cHRlZElkPUEwNzE4ODIxMktCWlhJMVlHWDFNMyZlbmNyeXB0ZWRBZElkPUExMDMwODk2Tk5OVkdZRTJISDVMJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ=='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Cache-Control': 'no-cache'
}
page = requests.get(URL, headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')
#I tried other parsing methods too: 'html.parser', 'html5lib'. Not helpful
title = soup.find(id="productTitle").get_text().strip()
# to prevent script from crashing when there isn't a price for the product
try:
price = soup.find(id='priceblock_ourprice').get_text().strip()
#convert price to float by slicing
convertedPrice = price[:8]
except:
price = 'not loaded'
convertedPrice = 'not loaded'
print(title) #returns correct string from the URL above
print(price)
print(convertedPrice)
Вывод
Neues Apple iPhone 12 Pro (128 GB) - Graphit
1.120,00 €
1.120,00
Но
Как упоминал @Chase, если это динамически генерируемый контент, вы можете попробовать Selenium, он может обрабатывать нагрузку с ее ожиданиями — добавив задержку, вы можете дождаться загрузки страницы, динамически генерируемого контента, а затем получить вашу информацию.
Комментарии:
1. Привет, спасибо за ваш ответ. У меня все та же проблема с вашим решением. Как я уже говорил выше, я застрял с AttributeError: объект ‘NoneType’ не имеет атрибута ‘get_text’, переменной ‘price’ не присвоено какое-либо значение. Почему-то я не понял, почему API BeautifulSoup не смог найти «id = priceblock_ourprice», хотя я вижу это в исходном коде.
2. Можно было бы временно воспроизвести поведение, которое вы пытались описать: 1. Запустите код в моей jupyterlab и получите ‘not loaded’ в качестве price 2. Запустив только price = soup.find(id= ‘priceblock_ourprice’).get_text().strip() в другой ячейке, я получилинформация о ценах, я также могу ее увидеть, если я распечатаю суп. Не уверен, почему это происходит, но, похоже, это временно.