Eu nunca tive que lidar com a análise de dados da Internet antes. Normalmente, todos os dados para o trabalho (analista de dados) vêm de descarregamentos da empresa usando uma interface interna simples, ou são formados por consultas sql a tabelas diretamente do armazenamento, se você precisar de algo mais complexo do que "olhar para a receita do anterior mês".
Portanto, eu queria dominar alguma ferramenta simples para analisar páginas html a fim de poder coletar dados da Internet usando código em um IDE conveniente sem envolver ferramentas de terceiros.
Os locais de coleta de dados foram selecionados com base no princĂpio “nĂŁo há bloqueador de analisador” e “algo interessante pode resultar da análise desses dados”. Portanto, a escolha recaiu sobre um sortido de pratos para a entrega de trĂŞs restaurantes em SĂŁo Petersburgo - "Tokyo City", "Eurasia" e "2 Berega". Eles tĂŞm aproximadamente o mesmo foco de culinária e uma variedade semelhante, portanto, há claramente algo para comparar.
Vou compartilhar o prĂłprio analisador por um dos restaurantes.
import requests
from bs4 import BeautifulSoup
import pandas as pd
import datetime
print(" : " + str(datetime.datetime.now()))
#
urllist = ['https://www.tokyo-city.ru/spisok-product/goryachie-blyuda1.html',
'https://www.tokyo-city.ru/spisok-product/sushi.html',
'https://www.tokyo-city.ru/spisok-product/rolly.html',
'https://www.tokyo-city.ru/spisok-product/nabory.html',
'https://www.tokyo-city.ru/spisok-product/new_lunches.html',
'https://www.tokyo-city.ru/spisok-product/pitctca.html',
'https://www.tokyo-city.ru/spisok-product/salaty.html',
'https://www.tokyo-city.ru/spisok-product/-supy-.html',
'https://www.tokyo-city.ru/spisok-product/goryachie-zakuski1.html',
'https://www.tokyo-city.ru/spisok-product/wok.html',
'https://www.tokyo-city.ru/spisok-product/pasta.html',
'https://www.tokyo-city.ru/spisok-product/gamburgery-i-shaverma.html',
'https://www.tokyo-city.ru/spisok-product/Tokio-FIT.html',
'https://www.tokyo-city.ru/spisok-product/deserty.html',
'https://www.tokyo-city.ru/spisok-product/childrensmenu.html',
'https://www.tokyo-city.ru/spisok-product/napitki1.html',
'https://www.tokyo-city.ru/new/',
'https://www.tokyo-city.ru/spisok-product/postnoe-menyu.html',
'https://www.tokyo-city.ru/hit/',
'https://www.tokyo-city.ru/vegetarian/',
'https://www.tokyo-city.ru/hot/',
'https://www.tokyo-city.ru/offers/',
'https://www.tokyo-city.ru/spisok-product/sauces.html',
'https://www.tokyo-city.ru/spisok-product/Pirogi-torty.html']
#
names_all = []
descriptions_all = []
prices_all = []
categories_all = []
url_all = []
weight_all = []
nutr_all = []
#
for url in urllist:
response = requests.get(url).text
soup = BeautifulSoup(response, features="html.parser")
items = soup.find_all('a', class_='item__name')
itemsURL = []
n = 0
for n, i in enumerate(items, start=n):
itemnotfullURL = i.get('href')
itemURL = 'https://www.tokyo-city.ru' + itemnotfullURL
itemsURL.extend({itemURL})
m = 0
namesList = []
descriptionsList = []
pricesList = []
weightList = []
nutrList = []
itemResponse = requests.get(itemURL).text
itemsSoup = BeautifulSoup(itemResponse, features="html.parser")
itemsInfo = itemsSoup.find_all('div', class_='item__full-info')
for m, u in enumerate(itemsInfo, start=m):
if (u.find('h1', class_='item__name') == None):
itemName = 'No data'
else:
itemName = u.find('h1', class_='item__name').text.strip()
if (u.find('p', class_='item__desc') == None):
itemDescription = 'No data'
else:
itemDescription = u.find('p', class_='item__desc').text.strip()
if (u.find('span', class_='item__price-value') == None):
itemPrice = '0'
else:
itemPrice = u.find('span', class_='item__price-value').text
if (u.find('div', class_='nutr-value') == None):
itemNutr = 'No data'
else:
itemNutr = u.find('div', class_='nutr-value').text.strip()
if (u.find('div', class_='item__weight') == None):
itemWeight = '0'
else:
itemWeight = u.find('div', class_='item__weight').text.strip()
namesList.extend({itemName})
descriptionsList.extend({itemDescription})
pricesList.extend({itemPrice})
weightList.extend({itemWeight})
nutrList.extend({itemNutr})
df = pd.DataFrame((
{'Name': namesList,
'Description': descriptionsList,
'Price': pricesList,
'Weight': weightList,
'NutrInfo': nutrList
}))
names_all.extend(df['Name'])
descriptions_all.extend(df['Description'])
prices_all.extend(df['Price'])
weight_all.extend(df['Weight'])
nutr_all.extend(df['NutrInfo'])
df['Category'] = soup.find('div', class_='title__container').text.strip()
categories_all.extend(df['Category'])
result = pd.DataFrame((
{'Name': names_all,
'Description': descriptions_all,
'Price': prices_all,
'Category': categories_all,
'NutrInfo': nutr_all,
'Weight': weight_all,
}))
print(" : " + str(datetime.datetime.now()))
- / . , . , , , - - .
- .
:
, , , , , , .
:
. , . , , , , .
City
“ City” 19 5 , , (, ). - 351.
“” - 13 , 301 . , “ City” , 40% , , , “”.
2
- 241 15 .
, , , .
â„–1: ?
, “” .
, , , . , “”, “ ”, “”, “”, “” “” + .
:
, “2 ” - №1 . , “” (“ City” - 20, “” - 17 “2 ” - 51).
- , “” .
â„–2: ?
, - “”, “” “ ”. . , , “ ”, .
100 , :
“2 ” , “ ”. , “ + ” . “ ” “ City” “”.
“ City” . “2 ” 2 . “” . 100 “” 30% ( , ), “ City” .
, :
“” . “” 30% .
“2 ” , . , “ ” , , 2 + ( ). .
“ City” .
â„–3: ?
, , . , .
“ City” 205 100 , . , . “2 ” 35% , . , , , .
: ?
, , , , .
Apesar do maior conteúdo calórico por 100 gramas e uma grande quantidade de fast food, “2 Shores” oferece um menu bastante equilibrado, enquanto o mesmo “Tokyo City” tem uma tendência clara para carboidratos.
BZHU "Eurasia" é de alguma forma uniforme demais, praticamente sem emissões, portanto levanta suspeitas.
De uma forma geral, existem dúvidas quanto à veracidade das conclusões que tirei especificamente nesta questão - talvez, para a resposta correta à questão, estes indicadores precisem de ser avaliados de alguma forma diferente.
Aqui está uma pesquisa tão pequena, mas curiosa, na minha opinião, que veio do pensamento aleatório “analisar algo”.