def inferir_ciudad(ciudad, provincia=None, estricto=False): nombreciudad = texto.normalizar(ciudad.replace(' ', '')) # ejemplo "Pto. Madryn" if '.' in nombreciudad: nombreciudad = nombreciudad.split('.')[1] buscar = "%sargentina" % nombreciudad try: ciudad = City.objects.get(name__iexact=ciudad) except (City.DoesNotExist, City.MultipleObjectsReturned): try: ciudad = City.objects.get(search_names__icontains=buscar) except (City.DoesNotExist, City.MultipleObjectsReturned): ciudad = None if ciudad and not estricto: return ciudad.name, ciudad.region.name, ciudad.id elif provincia: nombreprov = texto.normalizar(provincia.replace(' ', '')) buscar = "%s%sargentina" % (nombreciudad, nombreprov) try: ciudad = City.objects.get(search_names__istartswith=buscar) except (City.DoesNotExist, City.MultipleObjectsReturned): ciudad = None if ciudad: return ciudad.name, ciudad.region.name, ciudad.id
def _actualizar_busqueda(self, commit=True): """denormalizacion de varios atributos relacionados para agilizar una busqueda de sucursales por palabras claves""" claves = [] if self.nombre: nombre = texto.normalizar(self.nombre) # quitamos palabras comunes nombre = nombre.replace('sucursal', '').replace('supermercado', '') claves.append(nombre) if self.cadena: claves.append(texto.normalizar(self.cadena.nombre)) if self.ciudad: claves.append(texto.normalizar(self.ciudad.name)) if self.ciudad.region: claves.append(texto.normalizar(self.ciudad.region.name)) if self.direccion: claves.append(texto.normalizar(self.direccion)) self.busqueda = " ".join(claves) if commit: super(Sucursal, self).save(update_fields=['busqueda'])
def get_queryset(self): queryset = super(CityViewSet, self).get_queryset() q = self.request.QUERY_PARAMS.get('q', None) if q: q = texto.normalizar(q).replace(' ', '') queryset = queryset.filter(search_names__startswith=q)[:6] return queryset
def parse_suc(self, html_snippet): pq = PyQuery(html_snippet) data = {} data['nombre'] = 'Sucursal ' + pq('.name a').text() data['cadena_nombre'] = pq('.name + div img').attr('title') data['cadena_id'] = nombre2id[data['cadena_nombre']] data['direccion'] = pq('.name + div + div').text() prov_ciudad = pq('.name + div + div + div').text() normal_prov_ciudad = texto.normalizar(prov_ciudad) prov_ciudad = prov_ciudad.split() for p in PROVINCIAS: if p in normal_prov_ciudad: break else: assert ValueError("provincia en %s" % normal_prov_ciudad) # la pampa, la rioja sep = len(p.split()) data['provincia'] = " ".join(prov_ciudad[:sep]) data['ciudad'] = " ".join(prov_ciudad[sep:]) ciudad = inferir_ciudad(data['ciudad'], data['provincia']) if ciudad: data['ciudad_relacionada_id'] = ciudad[2] ubicacion = pq('.encuentra-la-ruta').attr('rel').split('l(')[1][:-1].split(', ') data['lat'], data['lon'] = ubicacion data['telefono'] = pq('.name + div + div + div + div').text().strip() return data
def buscar(self, q, limite=8): """ Busca sucursales por palabras claves en ``q``. por ejemplo: ciudad, calle, cadena, etc. """ q = texto.normalizar(q) words = q.split() palabras = Q(reduce(operator.and_, (Q(busqueda__icontains=w) for w in words if len(w) > 2))) return self.filter(palabras)
def test_alternativa_guarda_instancia(self): assert DescripcionAlternativa.objects.count() == 0 descripcion = "La misma salsa descripta distinto ;-)" self.p1.agregar_descripcion(descripcion) self.assertEqual(DescripcionAlternativa.objects.count(), 1) alternativa = DescripcionAlternativa.objects.all()[0] self.assertEqual(alternativa.producto, self.p1) self.assertEqual(alternativa.descripcion, descripcion) self.assertEqual(alternativa.busqueda, normalizar(descripcion))
def inferir_cadena(nombre): """si el nombre de una y sólo una cadena está en el nombre de la sucursal devolvemos esa cadena y su id""" result = None for cadena_normal, cadena, id in CADENAS: if cadena_normal in texto.normalizar(nombre): if result is None: result = cadena, id else: return None return result
def buscar(self, q, limite=8): """ Busca sucursales por palabras claves en ``q``. por ejemplo: ciudad, calle, cadena, etc. """ q = texto.normalizar(q) words = q.split() palabras = Q( reduce(operator.and_, (Q(busqueda__icontains=w) for w in words if len(w) > 2))) return self.filter(palabras)
def buscar(self, q, limite=8): """Si q son digitos, busca por código de barra. otras cadenas, busca por similaridad e inclusión de palabras clave en la descripción""" if q.isdigit(): productos = Producto.objects.filter(upc__startswith=q)[0:limite] else: q = texto.normalizar(q) words = q.split() palabras = Q( reduce(operator.and_, (Q(busqueda__icontains=w) for w in words if len(w) > 2))) tiene_palabras = Producto.objects.filter(palabras).values_list( 'id', flat=True) similares = Producto.objects.filter_o( busqueda__similar=q).values_list('id', flat=True) productos = Producto.objects.filter( Q(id__in=tiene_palabras) | Q(id__in=similares)).distinct()[0:limite] return productos
def buscar(self, q, limite=8): """Si q son digitos, busca por código de barra. otras cadenas, busca por similaridad e inclusión de palabras clave en la descripción""" if q.isdigit(): productos = Producto.objects.filter(upc__startswith=q)[0:limite] else: q = texto.normalizar(q) words = q.split() palabras = Q(reduce(operator.and_, (Q(busqueda__icontains=w) for w in words if len(w) > 2))) tiene_palabras = Producto.objects.filter( palabras).values_list('id', flat=True) similares = Producto.objects.filter_o( busqueda__similar=q).values_list('id', flat=True) productos = Producto.objects.filter(Q(id__in=tiene_palabras) | Q(id__in=similares)).distinct()[0:limite] return productos
# -*- coding: utf-8 -*- """ basado en el csv de datos. infiere marcas """ from tools.texto import normalizar import re from preciosa.precios.models import Categoria r = open('../articulos/art.csv') descrip = [l.split(';')[1] for l in r] descrip = [re.search(r'([^\d]*)', s).group().strip() for s in descrip] descrip = set(descrip) cat = [c.nombre for c in Categoria.objects.all()] cat = set(cat) cat = [c.replace('/', ' ').replace('-', ' ') for c in cat] cat = set([c.replace(' ', ' ').lower() for c in cat]) posibles_marcas = [] for desc in descrip: desc_normal = normalizar(desc) for c in cat: if ' ' + c + ' ' in desc_normal: posibles_marcas.append(normalizar(desc_normal).replace(' ' + c + ' ', '').strip()) elif desc_normal.startswith(c + ' '): posibles_marcas.append(normalizar(desc_normal).replace(c + ' ', '').strip())
def _actualizar_busqueda(self): busqueda = unicode(self).replace(' > ', ' ') self.busqueda = texto.normalizar(busqueda) super(Categoria, self).save(update_fields=['busqueda'])
# -*- coding: utf-8 -*- """ funciones comunes para scrappers de sucursales """ from tools import texto from preciosa.precios.models import Cadena from cities_light.models import City, Region PROVINCIAS = [texto.normalizar(prov.name) for prov in Region.objects.all()] CADENAS = [(texto.normalizar(cadena), cadena, id) for (cadena, id) in Cadena.objects.extra(select={'length':'Length(nombre)'}).order_by('-length').values_list('nombre', 'id')] def inferir_cadena(nombre): """si el nombre de una y sólo una cadena está en el nombre de la sucursal devolvemos esa cadena y su id""" result = None for cadena_normal, cadena, id in CADENAS: if cadena_normal in texto.normalizar(nombre): if result is None: result = cadena, id else: return None return result def inferir_ciudad(ciudad, provincia=None, estricto=False):
def save(self, *args, **kwargs): self.busqueda = texto.normalizar(self.descripcion) super(DescripcionAlternativa, self).save(*args, **kwargs)
def save(self, *args, **kwargs): self.busqueda = texto.normalizar(self.descripcion) super(Producto, self).save(*args, **kwargs)
def test_incluye_direccion(self): calle = u'Av San Martín' self.suc = SucursalFactory(direccion=calle) self.assertIn(texto.normalizar(calle), self.suc.busqueda) self.assertIn(self.suc, Sucursal.objects.buscar('san martin'))
# -*- coding: utf-8 -*- """ funciones comunes para scrappers de sucursales """ from tools import texto from preciosa.precios.models import Cadena from cities_light.models import City, Region PROVINCIAS = [texto.normalizar(prov.name) for prov in Region.objects.all()] CADENAS = [(texto.normalizar(cadena), cadena, id) for (cadena, id) in Cadena.objects.extra(select={ 'length': 'Length(nombre)' }).order_by('-length').values_list('nombre', 'id')] def inferir_cadena(nombre): """si el nombre de una y sólo una cadena está en el nombre de la sucursal devolvemos esa cadena y su id""" result = None for cadena_normal, cadena, id in CADENAS: if cadena_normal in texto.normalizar(nombre): if result is None: result = cadena, id else: return None return result def inferir_ciudad(ciudad, provincia=None, estricto=False):
# -*- coding: utf-8 -*- """ basado en el csv de datos. infiere marcas """ from tools.texto import normalizar import re from preciosa.precios.models import Categoria r = open('../articulos/art.csv') descrip = [l.split(';')[1] for l in r] descrip = [re.search(r'([^\d]*)', s).group().strip() for s in descrip] descrip = set(descrip) cat = [c.nombre for c in Categoria.objects.all()] cat = set(cat) cat = [c.replace('/', ' ').replace('-', ' ') for c in cat] cat = set([c.replace(' ', ' ').lower() for c in cat]) posibles_marcas = [] for desc in descrip: desc_normal = normalizar(desc) for c in cat: if ' ' + c + ' ' in desc_normal: posibles_marcas.append( normalizar(desc_normal).replace(' ' + c + ' ', '').strip()) elif desc_normal.startswith(c + ' '): posibles_marcas.append( normalizar(desc_normal).replace(c + ' ', '').strip())