Compare commits
64 Commits
loop-patch
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c9bfa60d8 | |||
| 341bdd90ac | |||
| 80f4f3e9fc | |||
| a014444305 | |||
| 5c09b714f5 | |||
| 6437960ec8 | |||
| 026b71abc9 | |||
| b743afed4e | |||
| 4adba7d017 | |||
| 57cdc465b8 | |||
| c81acebd9a | |||
| 37f04d5b44 | |||
| 21d1e48b62 | |||
| 7551806620 | |||
| 277f12e4ea | |||
| 5a7767dd82 | |||
| 11d20be5f9 | |||
| ded745ef17 | |||
| bae3c7f21d | |||
| 677485e355 | |||
| faba11986b | |||
| c26454e02a | |||
| 8d776b81c5 | |||
| 717155e4bb | |||
| 7596a3e67c | |||
| 10e190c673 | |||
| 7452978f65 | |||
| 2271c39601 | |||
| 9ca7f1793d | |||
| ae050b36de | |||
| 9b3af3aa06 | |||
| b065873608 | |||
| c0abc889c4 | |||
| 2a3fddea3d | |||
| a6eeb26534 | |||
| bfd7e87ece | |||
| 02fdb04de2 | |||
| 3fb3d5c6b7 | |||
| cc7700ad58 | |||
| 87c95135c1 | |||
| 12430fcd46 | |||
| 48fdda355c | |||
| 9b3d9b3a65 | |||
| c9c0eabe4e | |||
| 7aed398551 | |||
| b8c65fc17f | |||
| e789e63434 | |||
| 53ee839021 | |||
| da3522aa76 | |||
| aaf4818dbc | |||
| 371d61de66 | |||
| ef20eee6c9 | |||
| 85ad0dd3b2 | |||
| 9836da5921 | |||
| 5470667776 | |||
| 1919eeb88b | |||
| 183c78a769 | |||
| 730e6b6644 | |||
| 809cb9a766 | |||
| fa8aff500d | |||
| 3cea1cbd3b | |||
| dd9721ef16 | |||
| 724ba9923c | |||
| 6f7e9e11be |
5
LICENSE
5
LICENSE
@@ -1,5 +0,0 @@
|
|||||||
Copyright (C) YEAR by AUTHOR EMAIL
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
137
README.md
137
README.md
@@ -1,104 +1,49 @@
|
|||||||
# CENANDOODLE
|
## SCRAPE JUST EAT
|
||||||
|
|
||||||
Ordinare cibo con doodle in rete locale o anche no
|
Scarica liberamente tutti i dati e il menu di un ristorante presente su JustEat
|
||||||
|
|
||||||
|
## Dati raccolti:
|
||||||
|
- `Prodotti:`
|
||||||
|
- `Nome`
|
||||||
|
- `Descrizione`
|
||||||
|
- `Numero dei pezzi`
|
||||||
|
- `Prezzo`
|
||||||
|
- `Ristorante:`
|
||||||
|
- `Nome`
|
||||||
|
- `Via`
|
||||||
|
- `Numero di telefono`
|
||||||
|
- `Disponibilità consegna`
|
||||||
|
- `Disponiilità ritiro al ristorante`
|
||||||
|
- `Costo consegna`
|
||||||
|
- `Ordine minimo`
|
||||||
|
|
||||||
Doodle condiviso su rete locale per ordinare e organizzare cibo e bevande (se previste)
|
-----------------------------------
|
||||||
|
|
||||||
----------------------------------------
|
## INSTALLAZIONE
|
||||||
|
|
||||||
# JAWANNDENN
|
|
||||||
|
|
||||||
Git software da utilizzare
|
|
||||||
https://github.com/hartwork/jawanndenn
|
|
||||||
|
|
||||||
|
|
||||||
Si installa
|
|
||||||
|
|
||||||
pip3 install jawanndenn --user
|
|
||||||
|
|
||||||
o con git clone
|
|
||||||
|
|
||||||
git clone https://github.com/hartwork/jawanndenn
|
|
||||||
./setup.py install --user
|
|
||||||
|
|
||||||
si lancia
|
|
||||||
|
|
||||||
jawanndenn
|
|
||||||
La tua macchina quindi hosta il doodle all indirizzo 127.0.0.1:8080 e si avvia una copia di questa demo qui https://jawanndenn.de/
|
|
||||||
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
jawanndenn --help:
|
|
||||||
--debug Enable debug mode (default: disabled)
|
|
||||||
--host HOST Hostname or IP address to listen at (dfault 127.0.0.1)
|
|
||||||
--port PORT Port to listen at (default: 8080)
|
|
||||||
--url-prefix PATH Path to prepend to URLs (default: "")
|
|
||||||
--database-sqlite3 FILE File to write the database to (default: ~/jawanndenn.sqlite3)
|
|
||||||
--django-secret-key-file FILE File to use for Django secret key data (default: ~/jawanndenn.secret_key)
|
|
||||||
|
|
||||||
limit configuration:
|
|
||||||
--max-polls COUNT Maximum number of polls total (default: 1000)
|
|
||||||
--max-votes-per-poll COUNT Maximum number of votes per poll (default: 40)
|
|
||||||
|
|
||||||
data import/export arguments:
|
|
||||||
--dumpdata Dump a JSON export of the database to standard output, then quit.
|
|
||||||
--loaddata FILE.json Load a JSON export of the database from FILE.json, then quit.
|
|
||||||
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
# GOAL:
|
|
||||||
Estrapolare nomi dei piatti e formattarli per file json
|
|
||||||
|
|
||||||
|
|
||||||
Da fare:
|
|
||||||
|
|
||||||
Estrapola piatti da JustEat,
|
|
||||||
Estrapola prezzo,
|
|
||||||
Estrapola descrizione,
|
|
||||||
formatta i dati.
|
|
||||||
|
|
||||||
Funzionalità da aggiungere:
|
|
||||||
Visualizzare prezzo,
|
|
||||||
Visualizzare descrizione piatto,
|
|
||||||
Spesa totale,
|
|
||||||
Spesa dei singoli,
|
|
||||||
Visualizzazione del num telefono ristorante,
|
|
||||||
Eliminare un piatto,
|
|
||||||
Mostrare che non è disponibile o non mostrare un piatto se non c'è,
|
|
||||||
|
|
||||||
Funzionalità da aggiungere secondarie:
|
|
||||||
Specificare la scelta dell impasto speciale
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
FILE.json di esempio:
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
"lifetime": "month",
|
|
||||||
|
|
||||||
"equal_width": true,
|
|
||||||
|
|
||||||
"title": "Che ti vuoi mangià?",
|
|
||||||
|
|
||||||
"options": [
|
|
||||||
|
|
||||||
"Piatto Lahme Meshwie",
|
|
||||||
|
|
||||||
"Piatto Aleppo",
|
|
||||||
|
|
||||||
"Fatayer con Formaggio",
|
|
||||||
|
|
||||||
"Fatayer con Spinaci"
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Scarica il git
|
||||||
|
```bash
|
||||||
|
#Scarica il git
|
||||||
|
git clone https://repo.esiliati.org/scossa/scrapeje.git
|
||||||
|
#Entra nella cartella di scrapeje
|
||||||
|
cd scrapeje
|
||||||
|
```
|
||||||
|
|
||||||
|
Installa requirement
|
||||||
|
```bash
|
||||||
|
#Concedi i permessi di esecuzione al setup
|
||||||
|
chmod +x ./setup.sh
|
||||||
|
#Esegui il setup
|
||||||
|
./setup.sh
|
||||||
|
```
|
||||||
|
## UTILIZZO
|
||||||
|
lancia ScrapeJE
|
||||||
|
```bash
|
||||||
|
python3 scrapeje.py
|
||||||
|
```
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
|
||||||
|
||| Ordinare cibo in rete locale o su servizio hostato. A favore del cliente e del ristoratore in termini economici, evitanto commissioni intermediare, ma senza rinunciare alla comodità dei clic <br>
|
||||||
|
||| Aggiungere più pezzi dello stesso prodotto per singolo utente, <br>
|
||||||
|
||| calcolare e visualizzare il prezzo del singolo utente e il totale da dare al rider. <br>
|
||||||
127
ScrapeJE.py
127
ScrapeJE.py
@@ -1,127 +0,0 @@
|
|||||||
import requests
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import cloudscraper
|
|
||||||
import json
|
|
||||||
|
|
||||||
nome=[]
|
|
||||||
desc=[]
|
|
||||||
npezzi=[]
|
|
||||||
prezzo=[]
|
|
||||||
|
|
||||||
#prende l url della pagina justeat del ristorante in input
|
|
||||||
#linkJE = input('link della pagina justeat del ristorante: ') #decommenta per input manuale
|
|
||||||
|
|
||||||
#scrape html
|
|
||||||
scraper = cloudscraper.create_scraper(browser={'browser': 'firefox','platform': 'windows','mobile': False})
|
|
||||||
#page = scraper.get(linkJE).content #usa input manuale
|
|
||||||
page = scraper.get("https://www.justeat.it/restaurants-saporedialeppo/menu").content #usa input automatico
|
|
||||||
#crea il file html
|
|
||||||
with open('JEmenu.html', 'wb') as f:
|
|
||||||
f.write(page)
|
|
||||||
|
|
||||||
#apre e legge il file
|
|
||||||
with open('JEmenu.html', 'rb') as f:
|
|
||||||
page = f.read()
|
|
||||||
|
|
||||||
#parser
|
|
||||||
soup = BeautifulSoup(page, "html.parser")
|
|
||||||
menu = soup.find(attrs={"data-test-id": "menu-item"})
|
|
||||||
|
|
||||||
|
|
||||||
#Stora nome ristorante
|
|
||||||
nrist=soup.title.text[8:-32]
|
|
||||||
menu.find(attrs={"allergenPhoneNumber": "menu-item-name"})
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
#Stora il numero di telfono del ristorante
|
|
||||||
#info-> alla riga 870 dell html, all interno di uno <script> c'è il numero in forma-> "allergenPhoneNumber":"3389529446" (es riferito a quando si scrapa aleppo)
|
|
||||||
#tel=
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
#cicla le schede prodotto
|
|
||||||
for menu in soup.find_all(attrs={"data-test-id": "menu-item"}):
|
|
||||||
att=menu
|
|
||||||
#riempie la lista "nome"
|
|
||||||
for att in menu.find(attrs={"data-test-id": "menu-item-name"}):
|
|
||||||
if att != " ":
|
|
||||||
nome.append(att.lstrip().splitlines()[0])
|
|
||||||
|
|
||||||
#riempie la lista "desc"
|
|
||||||
att=menu.find("p", class_="c-menuItems-description")
|
|
||||||
if att != None:
|
|
||||||
for att in menu.find("p", class_="c-menuItems-description"):
|
|
||||||
desc.append(att.lstrip().splitlines()[0])
|
|
||||||
else:
|
|
||||||
desc.append(None)
|
|
||||||
|
|
||||||
#riempie la lista "prezzo"
|
|
||||||
for att in menu.find("p", class_="c-menuItems-price notranslate"):
|
|
||||||
prezzo.append(att.lstrip().splitlines()[0])
|
|
||||||
|
|
||||||
#riempie la lista "npezzi"
|
|
||||||
att=menu.find_all(attrs={"data-test-id": "menu-item-description"})
|
|
||||||
if att != None:
|
|
||||||
if menu.text.find("pezzo") > 0 or menu.text.find("pezzi") > 0:
|
|
||||||
npezzi.append(menu.text.splitlines()[7].lstrip())
|
|
||||||
else:
|
|
||||||
npezzi.append(None)
|
|
||||||
continue
|
|
||||||
|
|
||||||
#stampa liste
|
|
||||||
for x in range(len(nome)):
|
|
||||||
print("\n")
|
|
||||||
print(nome[x])
|
|
||||||
print(desc[x])
|
|
||||||
print(npezzi[x])
|
|
||||||
print(prezzo[x])
|
|
||||||
|
|
||||||
#stampa lunghezza liste e nome del risrorante # e numero di telefono
|
|
||||||
print("\n")
|
|
||||||
print(nrist)
|
|
||||||
#print(tel)
|
|
||||||
print("lista nome",len(nome))
|
|
||||||
print("lista desc:",len(desc))
|
|
||||||
print("lista npezzi:",len(npezzi))
|
|
||||||
print("lista prezzi:",len(prezzo)) #sono stringhe ovvero ci sono anche prezzi come "da 1,00 €" (servirà formattarla in double per poter fare i conti a fine doodle)
|
|
||||||
|
|
||||||
|
|
||||||
#Crea file json formattato per jawanndenn con la lista dei nomi dei prodotti
|
|
||||||
#scrive le prime righe del json (uguali ogni volta)
|
|
||||||
with open('jwndn.json', 'w') as jw:
|
|
||||||
jw.write("{\n")
|
|
||||||
jw.write(' "lifetime": "month",\n')
|
|
||||||
jw.write(' "equal_width": true,\n')
|
|
||||||
jw.write(' "title":')
|
|
||||||
jw.write('"')
|
|
||||||
jw.write(nrist)
|
|
||||||
jw.write('",')
|
|
||||||
jw.write("\n")
|
|
||||||
jw.write(' "options": \n')
|
|
||||||
|
|
||||||
#inserisce i nomi dei prodotti dalla lista
|
|
||||||
def writeListJSONFile(filepathname, lista):
|
|
||||||
with open('./jwndn.json', 'a+') as f:
|
|
||||||
json.dump(nome, f)
|
|
||||||
|
|
||||||
writeListJSONFile('./jwndn.json', nome)
|
|
||||||
|
|
||||||
#conclude il json con l ultima parentesi graffa
|
|
||||||
with open('jwndn.json', 'a+') as jw:
|
|
||||||
jw.write("\n}\n")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
#storare in "tel" il numero di telefono dle ristorante
|
|
||||||
#automatizzare l inserimento in jawandenn
|
|
||||||
|
|
||||||
#PS jawanndenn include la funzione per argomento
|
|
||||||
#"jawanndenn --loaddata FILE.json" --> Load a JSON export of the database from FILE.json, then quit.
|
|
||||||
|
|
||||||
#aggiungere la possibilità di mettere piu di un voto al doodle (ovvero prendere piu prodotti come es: 2 fatayer al formaggio)
|
|
||||||
|
|
||||||
#fare in modo che quando si passa il mouse sul nome del prodotto (nel doodle) compaiano descrizione, npezzi e prezzo
|
|
||||||
#forse per il prezzo trattamento diverso
|
|
||||||
#
|
|
||||||
383
scrapeje.py
Normal file
383
scrapeje.py
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
#IMPORTO MODULI
|
||||||
|
#selenium: scraper | bs4: parser | re: regex | os: interazione con os | shutil: interazione con la shell
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from jinja2 import Template
|
||||||
|
import time
|
||||||
|
|
||||||
|
restaurant_url=''
|
||||||
|
driver=''
|
||||||
|
page = ''
|
||||||
|
nrist=''
|
||||||
|
restaurant_address=''
|
||||||
|
tel=''
|
||||||
|
result=''
|
||||||
|
soup = ''
|
||||||
|
nristmax = '0'
|
||||||
|
nome=[]
|
||||||
|
desc=[]
|
||||||
|
npezzi=[]
|
||||||
|
prezzo=[]
|
||||||
|
prezzoN=[]
|
||||||
|
|
||||||
|
|
||||||
|
def inputurl():
|
||||||
|
global restaurant_url
|
||||||
|
global nristmax
|
||||||
|
#INPUT
|
||||||
|
#prende l url della pagina justeat del ristorante in input
|
||||||
|
print ("\nesempio: https://www.justeat.it/restaurants-pizzeria-la-garganica-bologna/menu")
|
||||||
|
restaurant_url = input('INSERISCI IL LINK DELLA PAGINA DEL RISTORANTE: ')
|
||||||
|
# PER DEBUG
|
||||||
|
#restaurant_url = 'https://www.justeat.it/restaurants-pizzeriadelrondone-bologna/menu'
|
||||||
|
|
||||||
|
|
||||||
|
def animazione():
|
||||||
|
def typewriter(text, delay=0.1):
|
||||||
|
for letter in text:
|
||||||
|
print(letter, end='', flush=True)
|
||||||
|
time.sleep(delay)
|
||||||
|
print()
|
||||||
|
|
||||||
|
typewriter("▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▇ ▆ ▅ ▄ ▃ ▁", 0.09)
|
||||||
|
|
||||||
|
|
||||||
|
def scraper():
|
||||||
|
global driver
|
||||||
|
global page
|
||||||
|
global restaurant_url
|
||||||
|
|
||||||
|
#FIREFOX
|
||||||
|
opts = webdriver.FirefoxOptions()
|
||||||
|
opts.headless = True
|
||||||
|
driver = webdriver.Firefox(options=opts)
|
||||||
|
driver.get(restaurant_url)
|
||||||
|
|
||||||
|
#CHROMIUM/CHROME
|
||||||
|
# driver = webdriver.Chrome()
|
||||||
|
# driver.get(restaurant_url)
|
||||||
|
|
||||||
|
animazione()
|
||||||
|
|
||||||
|
wait = WebDriverWait(driver, 16)
|
||||||
|
wait.until(EC.presence_of_element_located((By.CLASS_NAME, "c-menuItems-price")))
|
||||||
|
|
||||||
|
page = driver.page_source
|
||||||
|
|
||||||
|
with open('JEmenu.html', 'w') as f:
|
||||||
|
f.write(page)
|
||||||
|
|
||||||
|
|
||||||
|
def parser():
|
||||||
|
global soup
|
||||||
|
with open('JEmenu.html', 'r') as f:
|
||||||
|
page = f.read()
|
||||||
|
|
||||||
|
soup = BeautifulSoup(page, "html.parser")
|
||||||
|
|
||||||
|
|
||||||
|
def stora_tutto():
|
||||||
|
global nome
|
||||||
|
global desc
|
||||||
|
global npezzi
|
||||||
|
global prezzo
|
||||||
|
global prezzoN
|
||||||
|
global soup
|
||||||
|
global nrist
|
||||||
|
global restaurant_address
|
||||||
|
global tel
|
||||||
|
global result
|
||||||
|
|
||||||
|
#Stora nome ristorante
|
||||||
|
nrist = soup.title.text[8:-32]
|
||||||
|
|
||||||
|
#Stora telefono del ristorante
|
||||||
|
pattern = re.compile(r'allergenPhoneNumber')
|
||||||
|
script_tags = soup.find_all('script', string=pattern)
|
||||||
|
pattern = re.compile(r'"allergenPhoneNumber":"(\d+)"')
|
||||||
|
tel = re.search(pattern, script_tags[0].next)
|
||||||
|
if tel:
|
||||||
|
tel = tel.group(1)
|
||||||
|
|
||||||
|
#Stato ristorante
|
||||||
|
restaurant_is_open = menu = soup.find(attrs={"data-js-test":"order-status-wrapper"}).text
|
||||||
|
restaurant_is_open = restaurant_is_open.replace('\n', ' ')
|
||||||
|
regex = r" {4,}"
|
||||||
|
result = re.split(regex, restaurant_is_open)
|
||||||
|
|
||||||
|
#indirizzo ristorante
|
||||||
|
restaurant_address = soup.find(attrs={"data-js-test":"header-restaurantAddress"}).text
|
||||||
|
|
||||||
|
#cicla le schede prodotto
|
||||||
|
menu = soup.find(attrs={"data-test-id": "menu-item"})
|
||||||
|
for menu in soup.find_all(attrs={"data-test-id": "menu-item"}):
|
||||||
|
att=menu
|
||||||
|
#riempie la lista "nome"
|
||||||
|
for att in menu.find(attrs={"data-test-id": "menu-item-name"}):
|
||||||
|
if att != type(None):
|
||||||
|
if att != " ":
|
||||||
|
nome.append(att.lstrip().splitlines()[0])
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
#riempie la lista "desc"
|
||||||
|
att=menu.find("p", class_="c-menuItems-description")
|
||||||
|
if att != None:
|
||||||
|
for att in menu.find("p", class_="c-menuItems-description"):
|
||||||
|
desc.append(att.lstrip().splitlines()[0])
|
||||||
|
else:
|
||||||
|
desc.append(None)
|
||||||
|
|
||||||
|
#riempie la lista "prezzo"
|
||||||
|
for att in menu.find(attrs={"data-js-test": "menu-item-price"}):
|
||||||
|
#prezzo.append(att.lstrip().splitlines()[0])
|
||||||
|
counter=0
|
||||||
|
if att != " " and counter % 2 == 0:
|
||||||
|
prezzo.append(att.lstrip())
|
||||||
|
counter+=1
|
||||||
|
else:
|
||||||
|
counter+=1
|
||||||
|
continue
|
||||||
|
continue
|
||||||
|
|
||||||
|
#riempie la lista "npezzi"
|
||||||
|
att=menu.find_all(attrs={"data-test-id": "menu-item-description"})
|
||||||
|
if att != None:
|
||||||
|
if menu.text.find("pezzo") > 0 or menu.text.find("pezzi") > 0:
|
||||||
|
npezzi.append(menu.text.splitlines()[7].lstrip())
|
||||||
|
else:
|
||||||
|
npezzi.append(None)
|
||||||
|
continue
|
||||||
|
|
||||||
|
def parserdarubrica():
|
||||||
|
global parser
|
||||||
|
global stora_tutto
|
||||||
|
folder_path = ('./DATI_RUBRICA/')
|
||||||
|
for filename in os.listdir(folder_path):
|
||||||
|
if filename.startswith(scelta):
|
||||||
|
print(filename)
|
||||||
|
filename = filename.replace(' ', ' ')
|
||||||
|
print(filename)
|
||||||
|
shutil.copy (folder_path + filename, f'./JEmenu.html')
|
||||||
|
parser()
|
||||||
|
stora_tutto()
|
||||||
|
else:
|
||||||
|
print ("numero inesistente")
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
def stampa_liste(): #PER DEBUG
|
||||||
|
print("\n")
|
||||||
|
for x in range(len(nome)):
|
||||||
|
# print("\n")
|
||||||
|
print(nome[x])
|
||||||
|
print(desc[x])
|
||||||
|
print(npezzi[x])
|
||||||
|
print(prezzo[x])
|
||||||
|
|
||||||
|
|
||||||
|
def stampa_info():
|
||||||
|
print("-" * (len(desc)) + "\n")
|
||||||
|
print(nrist)
|
||||||
|
print(restaurant_address.strip())
|
||||||
|
print("Telefono:",tel,"\n")
|
||||||
|
|
||||||
|
doppione = ""
|
||||||
|
for i in range(len(result)):
|
||||||
|
if re.search(r"[a-zA-Z]", result[i]):
|
||||||
|
if (result[i]) == doppione:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print(result[i])
|
||||||
|
elif re.search(r"\d", result[i]):
|
||||||
|
print(result[i], result[i+1])
|
||||||
|
doppione = (result[i+1])
|
||||||
|
print("\n" + "-" * (len(desc))+ "\n")
|
||||||
|
|
||||||
|
|
||||||
|
def genera_prezzoN():
|
||||||
|
#Genera la lista prezzoN[] che è un clone di "prezzo[] ma con i valori float anzichè string"
|
||||||
|
global prezzoN
|
||||||
|
prezzoN = prezzo.copy()
|
||||||
|
for i in range(len(prezzo)):
|
||||||
|
if "€" in prezzo[i]:
|
||||||
|
prezzoN[i] = float(prezzo[i].replace("€", "").replace(",", ".").replace("da ", ""))
|
||||||
|
elif "Non" in prezzo[i]:
|
||||||
|
prezzoN[i] = 0
|
||||||
|
prezzoN[i] = float(prezzoN[i])
|
||||||
|
else:
|
||||||
|
prezzoN[i] = 99999
|
||||||
|
# for x in range(len(nome)): #PER DEBUG
|
||||||
|
# print(prezzoN[x])
|
||||||
|
|
||||||
|
html=''
|
||||||
|
def genera_frontend():
|
||||||
|
# IMPOSTA E GENERA pagina2.html CON IL FILE htmlpage.html
|
||||||
|
global nome
|
||||||
|
global desc
|
||||||
|
global npezzi
|
||||||
|
global prezzo
|
||||||
|
global prezzoN
|
||||||
|
global html
|
||||||
|
with open("template.html", "r") as file:
|
||||||
|
template_content = file.read()
|
||||||
|
|
||||||
|
template = Template(template_content)
|
||||||
|
html = template.render(
|
||||||
|
nrist=nrist,
|
||||||
|
nome=nome,
|
||||||
|
desc=desc,
|
||||||
|
npezzi=npezzi,
|
||||||
|
prezzo=prezzo,
|
||||||
|
prezzoN=prezzoN
|
||||||
|
)
|
||||||
|
with open("pagina2.html", "w") as file:
|
||||||
|
file.write(html)
|
||||||
|
|
||||||
|
|
||||||
|
def salvainrubrica():
|
||||||
|
global nristmax
|
||||||
|
maxn=0
|
||||||
|
def trova_nuovo_numero():
|
||||||
|
global maxn
|
||||||
|
file_list = os.listdir('./DATI_RUBRICA')
|
||||||
|
number_list = []
|
||||||
|
# Estare il numero
|
||||||
|
for file_name in file_list:
|
||||||
|
if file_name[0].isdigit():
|
||||||
|
number_list.append(int(file_name.split('-')[0]))
|
||||||
|
# trova il massimo
|
||||||
|
if number_list:
|
||||||
|
max_number = max(number_list)
|
||||||
|
maxn=(max_number + 1)
|
||||||
|
|
||||||
|
if os.path.exists('rubrica.txt'):
|
||||||
|
#SE LA RUBRICA ESISTE
|
||||||
|
with open('rubrica.txt', 'a+') as rubrica:
|
||||||
|
rubrica.seek(0)
|
||||||
|
data = rubrica.read()
|
||||||
|
if restaurant_url not in data:
|
||||||
|
#QUANDO IL RISTORATE NON E' PRESENTE IN RUBRICA
|
||||||
|
saveit = input('Vuoi salvare il ristorante in rubrica? [Y|N] ')
|
||||||
|
#PER DEBUG
|
||||||
|
#saveit = "y"
|
||||||
|
if saveit.upper() in ['YES', 'Y', 'SI', 'S']:
|
||||||
|
os.makedirs("DATI_RUBRICA", exist_ok=True)
|
||||||
|
trova_nuovo_numero()
|
||||||
|
nristmax=(str(maxn) + "-" + nrist + '.html')
|
||||||
|
shutil.move ('JEmenu.html', f'./DATI_RUBRICA/{nristmax}')
|
||||||
|
if data:
|
||||||
|
rubrica.write('\n')
|
||||||
|
rubrica.write(nristmax + '\n')
|
||||||
|
rubrica.write(nrist + '\n')
|
||||||
|
rubrica.write(restaurant_url + '\n')
|
||||||
|
print ('\nIl ristorante"',nrist + '" è stato salvato in rubrica\n')
|
||||||
|
else:
|
||||||
|
#QUANDO IL RISTORATE E' GIA' PRESENTE IN RUBRICA
|
||||||
|
os.remove("JEmenu.html")
|
||||||
|
else:
|
||||||
|
#QUANDO IL RISTORATE E' GIA' PRESENTE IN RUBRICA
|
||||||
|
os.remove("JEmenu.html")
|
||||||
|
|
||||||
|
else:
|
||||||
|
#SE LA RUBRICA NON ESISTE
|
||||||
|
with open('rubrica.txt', 'a+') as rubrica:
|
||||||
|
rubrica.seek(0)
|
||||||
|
data = rubrica.read()
|
||||||
|
#CHIEDE SE SI VUOLE SALVARE ALTRIMENTI PULISCE
|
||||||
|
saveit = input('Vuoi salvare il ristorante in rubrica? [Y|N] ')
|
||||||
|
#PER DEBUG
|
||||||
|
#saveit = "y"
|
||||||
|
if saveit.upper() in ['YES', 'Y', 'SI', 'S']:
|
||||||
|
os.makedirs("DATI_RUBRICA", exist_ok=True)
|
||||||
|
nristmax=("1" + "-" + nrist + '.html')
|
||||||
|
shutil.move ('JEmenu.html', f'./DATI_RUBRICA/{nristmax}')
|
||||||
|
|
||||||
|
if data:
|
||||||
|
rubrica.write('\n')
|
||||||
|
rubrica.write(nristmax + '\n')
|
||||||
|
rubrica.write(nrist + '\n')
|
||||||
|
rubrica.write(restaurant_url + '\n')
|
||||||
|
print ('\nIl ristorante "' + nrist + '" è stato salvato in rubrica')
|
||||||
|
print ('(Riavvia lo script per ordinare da rubrica)\n')
|
||||||
|
else:
|
||||||
|
#PULISCE
|
||||||
|
os.remove("JEmenu.html")
|
||||||
|
os.remove("rubrica.txt")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################################
|
||||||
|
#############################################################################################
|
||||||
|
#############################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
if os.path.exists('rubrica.txt') and os.path.exists('./DATI_RUBRICA'):
|
||||||
|
|
||||||
|
#wr = input('\nVuoi vedere la rubrica? [Y|N] ')
|
||||||
|
wr = 's'
|
||||||
|
if wr.upper() in ['YES', 'Y', 'SI', 'S']:
|
||||||
|
print( '\n', os.listdir('./DATI_RUBRICA'), '\n')
|
||||||
|
|
||||||
|
#scelta = input("Scegli un numero esistente o premi Enter per metterre un link: ")
|
||||||
|
scelta = '1'
|
||||||
|
parserdarubrica()
|
||||||
|
|
||||||
|
else:
|
||||||
|
inputurl()
|
||||||
|
scraper()
|
||||||
|
parser()
|
||||||
|
stora_tutto()
|
||||||
|
driver.quit()
|
||||||
|
else:
|
||||||
|
inputurl()
|
||||||
|
scraper()
|
||||||
|
parser()
|
||||||
|
stora_tutto()
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
stampa_liste()
|
||||||
|
stampa_info()
|
||||||
|
genera_prezzoN()
|
||||||
|
salvainrubrica()
|
||||||
|
genera_frontend()
|
||||||
|
|
||||||
|
driver = webdriver.Firefox()
|
||||||
|
animazione()
|
||||||
|
driver.get("file://" + os.path.abspath("pagina2.html"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# #PER DEBUG
|
||||||
|
# for x in range(len(prezzoN)):
|
||||||
|
# print(prezzoN[x])
|
||||||
|
# print("\n" + "-" * 25 + "\n")
|
||||||
|
# print ("lista prezzo: ",len(prezzo))
|
||||||
|
# print ("lista prezzoN: ",len(prezzoN))
|
||||||
|
# print ("lista nome: ",len(nome))
|
||||||
|
# print("\n" + "-" * 25 + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
# #PER DEBUG
|
||||||
|
#stampa lunghezza liste
|
||||||
|
# print("lista nome: ",len(nome))
|
||||||
|
# print("lista desc: ",len(desc))
|
||||||
|
# print("lista npezzi: ",len(npezzi))
|
||||||
|
# print("lista prezzi: ",len(prezzo)) #sono stringhe
|
||||||
|
# print("lista prezziN: ",len(prezzoN)) #sono numeri
|
||||||
|
# print("\n" + "-" * 25 + "\n")
|
||||||
|
|
||||||
|
#FA SCHIFO
|
||||||
|
# html += ' var popup = window.open("", "Popup", "width=200,height=100,top=" + ((window.innerHeight - 100) / 2) + ",left=" + ((window.innerWidth - 200) / 2));'
|
||||||
|
# html += ' popup.document.write("<p>Prodotto aggiunto</p>");'
|
||||||
|
# html += ' setTimeout(function(){ popup.close(); }, 1000);'
|
||||||
|
|
||||||
|
|
||||||
33
setup.sh
Normal file → Executable file
33
setup.sh
Normal file → Executable file
@@ -1,5 +1,32 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
pip3 install jawanndenn
|
|
||||||
|
echo "Installo i moduli python necessari nella cartella .venv"
|
||||||
|
python -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
echo
|
||||||
|
|
||||||
pip3 install requests
|
pip3 install requests
|
||||||
pip3 install BeautifulSoup4
|
pip3 install BeautifulSoup4
|
||||||
pip3 install cloudscraper
|
pip3 install selenium
|
||||||
|
|
||||||
|
#SCRAPEJE UTILIZZA I MODULI PREINSTALLATI:
|
||||||
|
# import re
|
||||||
|
# import os
|
||||||
|
# import shutil
|
||||||
|
#NON PIU UTILIZZATI:
|
||||||
|
# pip3 install colorama
|
||||||
|
# pip3 install cloudscraper
|
||||||
|
# pip3 install json
|
||||||
|
|
||||||
|
echo "Installo chromium (se non già installato) necessario per lo scrape"
|
||||||
|
echo
|
||||||
|
sudo apt update
|
||||||
|
if [ -f /etc/os-release ] && grep -q "NAME=\"Ubuntu\"" /etc/os-release; then
|
||||||
|
sudo apt install chromium-browser -y
|
||||||
|
else
|
||||||
|
sudo apt install chromium -y
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo "Attiva il virtualenv: source .venv/bin/activate"
|
||||||
|
echo "Poi lancia lo script: python3 scrapeje.py"
|
||||||
|
echo
|
||||||
|
|||||||
4
start.sh
4
start.sh
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
python3 ScrapeJE.py
|
|
||||||
wait 1
|
|
||||||
jawanndenn --loaddata jwndn.json
|
|
||||||
76
template.html
Normal file
76
template.html
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- <link rel="stylesheet" type="text/css" href="main.css" /> -->
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.grid-item {
|
||||||
|
/* background-color: rgba(255, 255, 255, 0.8); */
|
||||||
|
border: 1px solid #ff8d1a;
|
||||||
|
padding: 20px;
|
||||||
|
/* font-size: 30px; */
|
||||||
|
text-align: center;
|
||||||
|
/* grid-column-start: 1;
|
||||||
|
grid-column-end: 3; */
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body style="background-color: black; color: white">
|
||||||
|
<h1 style='text-align: center; color: #ff8d1a'>{{ nrist }} </h1>
|
||||||
|
|
||||||
|
<!-- <form id="usernameForm">
|
||||||
|
<input type="text" id="prodottiAggiunti" placeholder="Enter your username" />
|
||||||
|
<button type="button" onclick="addUser()">Add User</button>
|
||||||
|
</form> -->
|
||||||
|
</head>
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{% for index in range(nome|length) %}
|
||||||
|
<div class="grid-item">
|
||||||
|
<h2 style='text-align: center;'>{{ nome[index] }}</h2>
|
||||||
|
|
||||||
|
<div class="spazio">
|
||||||
|
<p style='text-align: center;'>{{ desc[index] }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style='text-align: center;'>Npezzi: {{ npezzi[index] }}</p>
|
||||||
|
<p style='text-align: center;'>{{ prezzoN[index] }}€</p>
|
||||||
|
<div style='text-align: center;'><button style='font-size: 1.2em;' onclick="aggiungiProdotto('{{ nome[index] }}', '{{ prezzoN[index] }}')">+1</button></div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br><hr><h2>Prodotti aggiunti</h2>
|
||||||
|
<div id="prodottiAggiunti"></div>
|
||||||
|
<div id="total">Total: €<span id="totalValue">0.00</span></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var totalValue = 0;
|
||||||
|
function aggiungiProdotto(nome, prezzoN) {
|
||||||
|
var prodotto = nome + ' (' + Number(prezzoN).toFixed(2) + '€)';
|
||||||
|
var box = document.getElementById('prodottiAggiunti');
|
||||||
|
box.innerHTML += '<p>' + prodotto + ' <button onclick="rimuoviProdotto(this, ' + prezzoN + ')">-1</button></p>';
|
||||||
|
totalValue += parseFloat(prezzoN);
|
||||||
|
updateTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTotal() {
|
||||||
|
document.getElementById('totalValue').innerText = totalValue.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rimuoviProdotto(element, prezzoN) {
|
||||||
|
totalValue -= parseFloat(prezzoN);
|
||||||
|
element.parentNode.remove();
|
||||||
|
updateTotal();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user