проблемы вставки базы данных postgres других персонажей через scrapy - PullRequest
0 голосов
/ 17 сентября 2018

Привет всем, я начинаю с scrapy и делаю scrapy в супермаркет, но в URL и названиях продуктов есть такие символы, как "ñ", поэтому, когда я его очищаю, он перестает сохранять эту информацию в моей базе данных и просто сохраняйте информацию до тех пор, пока она не столкнется с URL или именем с этим символом «-», в частности, я много читала о функциях кодирования и декодирования, и я перепробовала много решений, опубликованных здесь, но это не работает.

КОД СКРАПЫ

    # -*- coding: utf-8 -*-

import scrapy   
import psycopg2   #Para establecer conexion con la base de datos.

from scrapy.spiders import CrawlSpider, Rule   #Para la creacion del bot y sus reglas de busqueda   
from scrapy.linkextractors import LinkExtractor   #Para extraer link de las paginas visitadas
import time
#---------------------------------------------------------------------------------------------------------------------------------


# #Creando la conexion.
conn = psycopg2.connect(database="namedb", user="postgres", password="root", host="127.0.0.1", port="5432")
# #Creando cursor.
cur = conn.cursor()


#---------------------------------------------------------------------------------------------------------------------------------
#Funciones


def leer_datos(nombre_archivo):
    """Lee un archivo txt y devuelve un array donde cada posicion es una fila del archivo.
    Argumentos: 
    nombre_archivo: String. No debe tener la extension. 
    """

    array = []
    archivo = open(nombre_archivo + '.txt','r')
    linea = archivo.readline()
    while linea != '':
    # Lee el archivo por lineas y las agrega al array.

        cadena = linea.strip('\n')  #Saca el valor '\n' de la linea
        array.append(cadena)    #Agrega la linea al array
        linea = archivo.readline()
    archivo.close()  # Cierra archivo
    return array


def insertar_datos(nombre_archivo,cadena):
    """Inserta un string en una fila de un archivo txt.
    Argumentos:
    nombre_archivo: String. No debe tener la extension.
    cadena: String a escribir en el archivo.
    """

    archivo = open(nombre_archivo + '.txt', "r+")
    contenido = archivo.read()  #Lee todo el contenido y el cursor queda al final.
    final_de_archivo = archivo.tell()   #Obtiene la posicion del cursor. Se encuentra en el final (ver linea anterior).
    archivo.seek(final_de_archivo)  #El cursor queda al final del archivo y se evita que vuelva al inicio al escribir.
    archivo.write(cadena)
    archivo.write('\n')
    archivo.close()


#---------------------------------------------------------------------------------------------------------------------------------
#Clases

#Clase para la extracion de elementos.



class LiderItem(scrapy.Item):

    name_prod = scrapy.Field()
    pricing = scrapy.Field()
    category = scrapy.Field()
    description = scrapy.Field()
    supermarket = scrapy.Field()
    url = scrapy.Field()


#Clase principal del programa.
class LiderSpider(CrawlSpider):

    #Configuracion inicial
    custom_settings = {
        "CLOSESPIDER_ITEMCOUNT":25,   #Cantidad de elementos a buscar. Comienza a contar desde el 0.
        "CONCURRENT_REQUESTS":1,   #Cantidad de url que puede visitar a la vez.
        "CONCURRENT_ITEMS":1,   #Cantidad de elementos que puede visitar a la vez.
    }
    name = 'Lider'  #Nombre del bot
    allowed_domain = ['www.lider.cl']   #Dominios permitidos para las url que puede visitar.


    start_urls = ['https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgxorj']

    #Leyendo el archivo "visitados.txt". En caso de no existir se crea.
    file = open("Lider_visitados.txt", "a+") 
    datos_visitados = file.read()
    file.close()

    #Obteniendo las url visitadas.
    if datos_visitados == '':
        url_visitadas = None
    else:
        url_visitadas = []
        url_visitadas = leer_datos("Lider_visitados")   #Se reciben las url visitadas desde el archivo visitados.txt

    #Reglas para la extraccion de url.
    rules = (

        #deny no permite que visite las url que ya ha procesado. restrict_xpaths le restringe moverse horizontalmente solo por las siguentes paginas.
        Rule(LinkExtractor(deny = (url_visitadas), restrict_xpaths = ( '//*[@id="paginationBox"]/nav/ul[2]/li[6]/a'))),

        #restrict_xpaths le restringe moverse verticalmente solo por los item de la pagina actual.
        Rule(LinkExtractor( deny = (url_visitadas), restrict_xpaths = ('//*[starts-with(@class,"product-link")]')),

        #Una vez que consigue las url llama mediante callback a la funcion 'parse_item' para procesar y extraer los datos.
                            callback = 'parse_item', follow = False)
    )


    def parse_item(self, response):
        """Recibe una pagina y extrae los datos para luego guardarlos en la base de datos."""

        item = LiderItem()

        #Extrayendo informacion.
        direccion_url = response.url
        item['name_prod'] = response.xpath('normalize-space(//span[@class="product-descript"]/text())').extract_first()
        item['pricing']  = response.xpath('normalize-space(//p[@class="price"])').extract_first()
        item['category'] = 'salsas'
        item['description'] = 'ninguna'
        item['supermarket'] = 'lider'
        item['url'] = direccion_url.encode("utf-8")



        print("\n >>>> EL NOMBRE ES: {0} \n LA URL ES: {1} \n\n".format(item['name_prod'].encode("utf-8"), item['url'].encode("utf-8")))
        time.sleep(5)

        #Preparando sentencia para ingresar datos en base de datos.
        valores = "INSERT INTO products(nombre,precio,categoria,descripcion,supermercado,url) VALUES (%s,%s,%s,%s,%s,%s);"
        data = (item['name_prod'],item['pricing'],item['category'],item['description'],item['supermarket'],item['url'])


        try:
            #Insertando datos en base de datos.
            cur.execute(valores,data)
            conn.commit()

            #Registrando la url procesada en archivo de url visitadas.
            insertar_datos("Lider_visitados",direccion_url)

            print("Datos insertados correctamente.\n")
        except:
            print("NO se han insertado.")
            print("---------------------")
        yield item

По сути, этот код выполняет переход на страницу, которую я ему дал, и сохраняет информацию, они сохраняются в текстовом файле и их пытаются сохранить в моей базе данных, и каждый раз, когда он запускает этот код, он использует TXT-файл, чтобы проверить, был ли этот продукт уже очищен, не сохраняйте его снова в базе данных

ДЛЯ ПРИМЕРА: это работает хорошо, но когда сталкивается с этой ссылкой:

https://www.lider.cl/supermercado/product/Maggi-Salsa-de-Tomates-Tuco-con-Champiñones-Tarro/813804

это не удалось, потому что я думаю, что у него есть - в URL-адресе и в названии продукта "Salsa de Tomates Tuco con Champiñones", но копирование продолжается, просто оно не сохраняет никакой другой информации в моей базе данных или в мой текстовый файл, даже когда другие продукты не имеют -.

ЗДЕСЬ БАЗА ДАННЫХ

CREATE TABLE products(
    product_id SERIAL,
    nombre VARCHAR(40),
    precio VARCHAR(10),
    categoria VARCHAR(20),
    descripcion VARCHAR(200),
    supermercado VARCHAR(20),
    url VARCHAR(200),

    PRIMARY KEY(product_id)
);

Пример того, что он сохраняет в текстовом файле

https://www.lider.cl/supermercado/product/Carozzi-Pasta-Vitaminizada-Fetuccine-88-Bolsa/299553
https://www.lider.cl/supermercado/product/Carozzi-Fideos-Fusilli-Tricolor-Bolsa/268340
https://www.lider.cl/supermercado/product/Carozzi-Spaghetti-Integral-Vitaminizado-Bolsa/338525

ЖУРНАЛ CMD

C:\Users\Emilio\Desktop\U\8VO SEMESTRE\Ingeniería de Software II\Proyecto\Scrape
o>scrapy runspider lider2.py
2018-09-17 14:40:59 [scrapy.utils.log] INFO: Scrapy 1.5.0 started (bot: scrapybo
t)
2018-09-17 14:40:59 [scrapy.utils.log] INFO: Versions: lxml 4.2.1.0, libxml2 2.9
.5, cssselect 1.0.3, parsel 1.4.0, w3lib 1.19.0, Twisted 17.5.0, Python 2.7.14 |
Anaconda, Inc.| (default, Mar 27 2018, 12:30:54) [MSC v.1500 64 bit (AMD64)], py
OpenSSL 17.5.0 (OpenSSL 1.0.2o  27 Mar 2018), cryptography 2.2.2, Platform Windo
ws-7-6.1.7601-SP1
2018-09-17 14:40:59 [scrapy.crawler] INFO: Overridden settings: {'SPIDER_LOADER_
WARN_ONLY': True, 'CLOSESPIDER_ITEMCOUNT': 25, 'CONCURRENT_ITEMS': 1, 'CONCURREN
T_REQUESTS': 1}
2018-09-17 14:40:59 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.closespider.CloseSpider',
 'scrapy.extensions.logstats.LogStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.corestats.CoreStats']
2018-09-17 14:41:00 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2018-09-17 14:41:00 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2018-09-17 14:41:00 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2018-09-17 14:41:00 [scrapy.core.engine] INFO: Spider opened
2018-09-17 14:41:00 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pag
es/min), scraped 0 items (at 0 items/min)
2018-09-17 14:41:00 [scrapy.extensions.telnet] DEBUG: Telnet console listening o
n 127.0.0.1:6023
2018-09-17 14:41:04 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgxorj> (referer: Non
e)
2018-09-17 14:41:04 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET
 https://www.lider.cl/supermercado/product/Malloa-Salsa-de-Tomates-Italiana/3369
> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicate
s)
2018-09-17 14:41:07 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgxorj?No=40&isNavReq
uest=Yes&Nrpp=40&page=2> (referer: https://www.lider.cl/supermercado/category/De
spensa/Pastas-y-Salsas/_/N-pgxorj)
2018-09-17 14:41:09 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Carozzi-Pasta-Vitaminizada-Fetuccine-88-Bolsa/29955
3> (referer: https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas
/_/N-pgxorj)
Datos insertados correctamente.

2018-09-17 14:41:14 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Carozzi-Pasta-Vitaminizada-Fetuccine-88-Bolsa/29955
3>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Pasta Vitaminizada Fetuccine 88 Bolsa',
 'pricing': u'$690',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Carozzi-Pasta-Vitaminizada-Fe
tuccine-88-Bolsa/299553'}
2018-09-17 14:41:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Carozzi-Fideos-Fusilli-Tricolor-Bolsa/268340> (refe
rer: https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgx
orj?No=40&isNavRequest=Yes&Nrpp=40&page=2)
Datos insertados correctamente.

2018-09-17 14:41:19 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Carozzi-Fideos-Fusilli-Tricolor-Bolsa/268340>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Fideos Fusilli Tricolor Bolsa',
 'pricing': u'$590',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Carozzi-Fideos-Fusilli-Tricol
or-Bolsa/268340'}
2018-09-17 14:41:19 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Carozzi-Spaghetti-Integral-Vitaminizado-Bolsa/33852
5> (referer: https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas
/_/N-pgxorj?No=40&isNavRequest=Yes&Nrpp=40&page=2)
Datos insertados correctamente.

2018-09-17 14:41:24 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Carozzi-Spaghetti-Integral-Vitaminizado-Bolsa/33852
5>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Spaghetti Integral Vitaminizado Bolsa',
 'pricing': u'$590',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Carozzi-Spaghetti-Integral-Vi
taminizado-Bolsa/338525'}
2018-09-17 14:41:24 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Maggi-Salsa-de-Tomates-Tuco-con-Champi%C3%B1ones-Ta
rro/813804> (referer: https://www.lider.cl/supermercado/category/Despensa/Pastas
-y-Salsas/_/N-pgxorj?No=40&isNavRequest=Yes&Nrpp=40&page=2)
NO se han insertado.
---------------------
2018-09-17 14:41:29 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Maggi-Salsa-de-Tomates-Tuco-con-Champi%C3%B1ones-Ta
rro/813804>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Salsa de Tomates Tuco con Champi\xc3\xb1ones Tarro',
 'pricing': u'$950',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Maggi-Salsa-de-Tomates-Tuco-c
on-Champi%C3%B1ones-Tarro/813804'}
2018-09-17 14:41:29 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Pomarola-Salsa-de-Tomates-Casera-con-Cubitos-de-Tom
ates-Doypack/371659> (referer: https://www.lider.cl/supermercado/category/Despen
sa/Pastas-y-Salsas/_/N-pgxorj?No=40&isNavRequest=Yes&Nrpp=40&page=2)
NO se han insertado.
---------------------
2018-09-17 14:41:35 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Pomarola-Salsa-de-Tomates-Casera-con-Cubitos-de-Tom
ates-Doypack/371659>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Salsa de Tomates Casera con Cubitos de Tomates Doypack',
 'pricing': u'$470',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Pomarola-Salsa-de-Tomates-Cas
era-con-Cubitos-de-Tomates-Doypack/371659'}
2018-09-17 14:41:35 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Trattoria-Fideos-Fusilli-Bolsa/270370> (referer: ht
tps://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgxorj?No=
40&isNavRequest=Yes&Nrpp=40&page=2)
2018-09-17 14:41:35 [scrapy.crawler] INFO: Received SIGINT, shutting down gracef
ully. Send again to force
2018-09-17 14:41:35 [scrapy.core.scraper] ERROR: Spider error processing <GET ht
tps://www.lider.cl/supermercado/product/Trattoria-Fideos-Fusilli-Bolsa/270370> (
referer: https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N
-pgxorj?No=40&isNavRequest=Yes&Nrpp=40&page=2)
Traceback (most recent call last):
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\utils\defer.py", line
 102, in iter_errback
    yield next(it)
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\spidermiddlewares\off
site.py", line 30, in process_spider_output
    for x in result:
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\spidermiddlewares\ref
erer.py", line 339, in <genexpr>
    return (_set_referer(r) for r in result or ())
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\spidermiddlewares\url
length.py", line 37, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\spidermiddlewares\dep
th.py", line 58, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "C:\ProgramData\Miniconda2\lib\site-packages\scrapy\spiders\crawl.py", li
ne 78, in _parse_response
    for requests_or_item in iterate_spider_output(cb_res):
  File "C:\Users\Emilio\Desktop\U\8VO SEMESTRE\IngenierÝa de Software II\Proyect
o\Scrapeo\lider2.py", line 156, in parse_item
    time.sleep(5)
IOError: [Errno 4] Interrupted function call
2018-09-17 14:41:35 [scrapy.core.engine] INFO: Closing spider (shutdown)
2018-09-17 14:41:36 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.l
ider.cl/supermercado/product/Lucchetti-Fideos-Cabellitos-Bolsa/296761> (referer:
 https://www.lider.cl/supermercado/category/Despensa/Pastas-y-Salsas/_/N-pgxorj?
No=40&isNavRequest=Yes&Nrpp=40&page=2)
NO se han insertado.
---------------------
2018-09-17 14:41:41 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.l
ider.cl/supermercado/product/Lucchetti-Fideos-Cabellitos-Bolsa/296761>
{'category': 'salsas',
 'description': 'ninguna',
 'name_prod': 'Fideos Cabellitos Bolsa',
 'pricing': u'$660',
 'supermarket': 'lider',
 'url': 'https://www.lider.cl/supermercado/product/Lucchetti-Fideos-Cabellitos-B
olsa/296761'}
2018-09-17 14:41:41 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 4542,
 'downloader/request_count': 9,
 'downloader/request_method_count/GET': 9,
 'downloader/response_bytes': 612918,
 'downloader/response_count': 9,
 'downloader/response_status_count/200': 9,
 'dupefilter/filtered': 80,
 'finish_reason': 'shutdown',
 'finish_time': datetime.datetime(2018, 9, 17, 17, 41, 41, 696000),
 'item_scraped_count': 6,
 'log_count/DEBUG': 17,
 'log_count/ERROR': 1,
 'log_count/INFO': 8,
 'request_depth_max': 2,
 'response_received_count': 9,
 'scheduler/dequeued': 9,
 'scheduler/dequeued/memory': 9,
 'scheduler/enqueued': 83,
 'scheduler/enqueued/memory': 83,
 'spider_exceptions/IOError': 1,
 'start_time': datetime.datetime(2018, 9, 17, 17, 41, 0, 969000)}
2018-09-17 14:41:41 [scrapy.core.engine] INFO: Spider closed (shutdown)

C:\Users\Emilio\Desktop\U\8VO SEMESTRE\Ingeniería de Software II\Proyecto\Scrape
o>

он остановился, потому что когда я увидел ошибку, я остановил ее и поэтому не сделал журнал cmd очень длинным, спасибо

заранее спасибо

1 Ответ

0 голосов
/ 17 сентября 2018

Я не слишком знаком со Scrapy, но я полагаю, что ваша проблема может быть в том, что вы подозревали - в кодировке.


Я вижу здесь, что вы закодировали URL:

item['url'] = direccion_url.encode("utf-8")

Однако это единственное, что вы закодировали. Вы упомянули

у него есть - в URL и в названии продукта

Вы не закодировали название продукта.

item['name_prod'] = response.xpath('normalize-space(//span[@class="product-descript"]/text())').extract_first()

Попробуйте изменить код выше:

item['name_prod'] = response.xpath('normalize-space(//span[@class="product-descript"]/text())').extract_first().encode("utf-8")

Любые другие поля, которые могут содержать специальные символы, также должны быть закодированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...