#python #api #web-scraping #python-requests
Вопрос:
Я пытаюсь очистить веб-сайт с помощью python, однако я не могу получить правильный API с запросами, потому что не могу получить информацию о продукте:
Это веб-сайт, кто-то может получить ответ API с информацией о продуктах, такой как название и цена? Obs: Важно заметить, что продукт веб-сайта загружается при прокрутке вниз.
https://www.atacadao.com.br/bebidas/
Если я не смогу сделать это с помощью запросов, я, вероятно, выберу селен, которого я действительно хотел избежать из-за его низкой эффективности для очистки.
Заранее спасибо 🙂
Комментарии:
1. если страница загружает данные при прокрутке вниз , то она использует
JavaScript
, ноrequests
Beatifulsoup
не может работатьJavaScript
, и вам может потребоваться использовать Selenium для управления реальным веб-браузером, который может работатьJavaScript
2. что ты пробовал? Где ваш код? Мы не будем писать весь код за вас. Если вы знаете, что он использует API, то вы могли бы показать все детали, которые у вас есть. И поставьте все под сомнение (не в комментариях) — это будет более читабельно и больше людей увидят это.
Ответ №1:
Использование DevTools
в Firefox
/ Chrome
(вкладка: Network
, фильтр: xhr
) Я обнаружил, что JavaScript
данные считываются в формате JSON с URL-адреса
Так что, используя requests
я могу запустить
import requests
url = 'https://www.atacadao.com.br/catalogo/search/?q=amp;category_id=nullamp;category[]=bebidasamp;page=1amp;order_by=-relevance'
r = requests.get(url)
print(r.text[:1000]) # show only beginning of data
print('------------')
data = r.json()
for item in data['results'][:3]: # I use `[:3]` to show only first three results
#print(item.keys())
#for key, val in item.items():
# print(f'{key}: {val}')
print('name:', item['name'])
print('price:', item['price'])
print('url:', item['url'])
print('---')
получить
{"paginator": {"page_range": [1, 2, 3, 4, 5], "page_number": 1, "last": 157, "first": "", "previous": "", "next": 2}, "results": [{"pk": 4854, "full_display": "Refrigerante lata 350ml - Coca Cola", "name": "Refrigerante", "brand": "Coca Cola", "type": "", "category": "Refrigerantes", "unit": "UN", "cart": {"cart": false, "multiplier": "", "count": "", "distributor_id": null, "distributor_name": null}, "photo_url": ["https://media.cotabest.com.br/media/sku/refrigerante-coca-cola-lata-350ml-coca-cola-un.png"], "price": {"price": "2,05", "multiplier": 6.0, "distributor_name": "ATACADu00c3O CD BELu00c9M", "distributor_id": 84022367}, "highlight": true, "price_statistics": {"quantity_prices": 20, "discount": 31, "cheaper": {"price": "2,05", "multiplier": 6.0, "distributor_name": "ATACADu00c3O CD BELu00c9M", "distributor_id": 84022367}, "expensive": "2.99"}, "multipliers": [{"unit_price": "2.05", "multiplier": "6.00", "distributor_id": 84022367}, {"unit_price": "2.05", "multiplier": "6.0
------------
name: Refrigerante
price: {'price': '2,05', 'multiplier': 6.0, 'distributor_name': 'ATACADÃO CD BELÉM', 'distributor_id': 84022367}
url: /refrigerante-coca-cola-lata-350ml
---
name: Refrigerante
price: {'price': '7,12', 'multiplier': 6.0, 'distributor_name': 'PMG', 'distributor_id': 4921}
url: /refrigerante-coca-cola-pet-2litros
---
name: Whisky
price: {'price': '89,00', 'multiplier': 12.0, 'distributor_name': 'ATACADÃO CD BETIM', 'distributor_id': 74133922}
url: /whisky-red-label-johnnie-walker-garrafa-1litro
---
Url имеет page=1
, поэтому я могу использовать его с разными значениями для загрузки других страниц.
Но я буду использовать словарь с парами, чтобы упростить его
url = 'https://www.atacadao.com.br/catalogo/search/'
payload = {
'q': '',
'category_id': 'null',
'category[]': 'bebidas',
'page': 1,
'order_by': '-relevance'
}
payload['page'] = 1 # 2, 3, etc.
r = requests.get(url, params=payload)
Полный код
import requests
url = 'https://www.atacadao.com.br/catalogo/search/'
payload = {
'q': '',
'category_id': 'null',
'category[]': 'bebidas',
'page': 1,
'order_by': '-relevance'
}
for number in range(1, 6):
print('n=== page:', number, '===n')
payload['page'] = number
r = requests.get(url, params=payload)
#print(r.text[:1000])
data = r.json()
for item in data['results']: #[:3]: # I use `[:3]` to show only first three results
#print(item.keys())
print('name:', item['name'])
print('price:', item['price'])
print('url:', item['url'])
print('---')
Результат:
=== page: 1 ===
name: Refrigerante
price: {'price': '2,05', 'multiplier': 6.0, 'distributor_name': 'ATACADÃO CD BELÉM', 'distributor_id': 84022367}
url: /refrigerante-coca-cola-lata-350ml
---
name: Refrigerante
price: {'price': '7,12', 'multiplier': 6.0, 'distributor_name': 'PMG', 'distributor_id': 4921}
url: /refrigerante-coca-cola-pet-2litros
---
name: Whisky
price: {'price': '89,00', 'multiplier': 12.0, 'distributor_name': 'ATACADÃO CD BETIM', 'distributor_id': 74133922}
url: /whisky-red-label-johnnie-walker-garrafa-1litro
---
=== page: 2 ===
name: Whisky
price: {'price': '39,83', 'multiplier': 1.0, 'distributor_name': 'ATACADÃO CD IGARASSU', 'distributor_id': 95849062}
url: /whisky-escoces-passport-garrafa-1litro
---
name: Refrigerante
price: {'price': '1,95', 'multiplier': 6.0, 'distributor_name': 'ATACADÃO CD MANAUS', 'distributor_id': 84019700}
url: /refrigerante-laranja-fanta-lata-350ml
---
name: Suco Integral
price: {'price': '10,97', 'multiplier': 6.0, 'distributor_name': 'ATACADÃO CD VILA VELHA', 'distributor_id': 96142380}
url: /suco-integral-sabor-uva-aurora-vidro-15litros
---
кстати:
Внутри JSON
вы можете видеть
"paginator": {"page_range": [1, 2, 3, 4, 5], "page_number": 1, "last": 157, "first": "", "previous": "", "next": 2}
и вы можете использовать while True
loop with number = data["paginator"]["next"]
для загрузки всех страниц.
Я проверил, что на последней странице есть пустая строка next
.
number = "1"
while True:
print('n=== page:', number, '===n')
payload['page'] = number
r = requests.get(url, params=payload)
#print(r.text[:1000]) # show only beginning of data
data = r.json()
for item in data['results'][:3]: # show only first three results
#print(item.keys())
print('name:', item['name'])
print('price:', item['price'])
print('url:', item['url'])
print('---')
number = data['pagination']['next']
if not number:
break
Я поместил код из своего ответа на GitHub python-примеры в папку __scraping__
Комментарии:
1. Я поместил код из своего ответа на GitHub python-примеры в папку
__scraping__
2. Большое вам спасибо, все получилось! И спасибо также за ваше объяснение, некоторые концепции для меня новы, потому что я начал учиться извлекать данные API только на этой неделе, и до сих пор я делал только один веб-сайт, принимающий данные API с запросами. Я постараюсь лучше изучить ваш код и, возможно, вернусь с некоторыми сомнениями, если это вас устроит, ха-ха.. И я собираюсь последовать за тобой в твоем мерзавце! С уважением 🙂
3. Кстати: есть страница с поддельными данными, чтобы научиться соскабливать toscrape.com он был создан авторами модуля Scrapy