在Firefox/Chrome 中使用DevTools(标签:Network,过滤器:xhr)我发现JavaScript 从 URL 读取数据为 JSON
https://www.atacadao.com.br/catalogo/search/?q=&category_id=null&category[]=bebidas&page=1&order_by=-relevance
所以使用requests 我可以运行
import requests
url = 'https://www.atacadao.com.br/catalogo/search/?q=&category_id=null&category[]=bebidas&page=1&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": "ATACAD\u00c3O CD BEL\u00c9M", "distributor_id": 84022367}, "highlight": true, "price_statistics": {"quantity_prices": 20, "discount": 31, "cheaper": {"price": "2,05", "multiplier": 6.0, "distributor_name": "ATACAD\u00c3O CD BEL\u00c9M", "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 循环和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-examples 的文件夹 __scraping__ 中