spider how example create mysql scrapy pipeline web-crawler

how - Escribir elementos en una base de datos MySQL en Scrapy



scrapy media pipeline (3)

Creo que esta manera es mejor y más concisa:

#Item class pictureItem(scrapy.Item): topic_id=scrapy.Field() url=scrapy.Field() #SQL self.save_picture="insert into picture(`url`,`id`) values(%(url)s,%(id)s);" #usage cur.execute(self.save_picture,dict(item))

Es como

cur.execute("insert into picture(`url`,`id`) values(%(url)s,%(id)s)" % {"url":someurl,"id":1})

Causa (puedes leer más sobre Items en Scrapy)

La clase Field es solo un alias de la clase dict incorporada y no proporciona ninguna funcionalidad o atributos adicionales. En otras palabras, los objetos de campo son simples dictados de Python.

Soy nuevo en Scrapy, tenía el código spider

class Example_spider(BaseSpider): name = "example" allowed_domains = ["www.example.com"] def start_requests(self): yield self.make_requests_from_url("http://www.example.com/bookstore/new") def parse(self, response): hxs = HtmlXPathSelector(response) urls = hxs.select(''//div[@class="bookListingBookTitle"]/a/@href'').extract() for i in urls: yield Request(urljoin("http://www.example.com/", i[1:]), callback=self.parse_url) def parse_url(self, response): hxs = HtmlXPathSelector(response) main = hxs.select(''//div[@id="bookshelf-bg"]'') items = [] for i in main: item = Exampleitem() item[''book_name''] = i.select(''div[@class="slickwrap full"]/div[@id="bookstore_detail"]/div[@class="book_listing clearfix"]/div[@class="bookstore_right"]/div[@class="title_and_byline"]/p[@class="book_title"]/text()'')[0].extract() item[''price''] = i.select(''div[@id="book-sidebar-modules"]/div[@class="add_to_cart_wrapper slickshadow"]/div[@class="panes"]/div[@class="pane clearfix"]/div[@class="inner"]/div[@class="add_to_cart 0"]/form/div[@class="line-item"]/div[@class="line-item-price"]/text()'').extract() items.append(item) return items

Y el código de la tubería es:

class examplePipeline(object): def __init__(self): self.dbpool = adbapi.ConnectionPool(''MySQLdb'', db=''blurb'', user=''root'', passwd=''redhat'', cursorclass=MySQLdb.cursors.DictCursor, charset=''utf8'', use_unicode=True ) def process_item(self, spider, item): # run db query in thread pool assert isinstance(item, Exampleitem) query = self.dbpool.runInteraction(self._conditional_insert, item) query.addErrback(self.handle_error) return item def _conditional_insert(self, tx, item): print "db connected-=========>" # create record if doesn''t exist. tx.execute("select * from example_book_store where book_name = %s", (item[''book_name'']) ) result = tx.fetchone() if result: log.msg("Item already stored in db: %s" % item, level=log.DEBUG) else: tx.execute("""INSERT INTO example_book_store (book_name,price) VALUES (%s,%s)""", (item[''book_name''],item[''price'']) ) log.msg("Item stored in db: %s" % item, level=log.DEBUG) def handle_error(self, e): log.err(e)

Después de ejecutar esto me sale el siguiente error

exceptions.NameError: global name ''Exampleitem'' is not defined

Recibí el error anterior cuando agregué el código siguiente en el método process_item

assert isinstance(item, Exampleitem)

y sin añadir esta linea estoy consiguiendo

**exceptions.TypeError: ''Example_spider'' object is not subscriptable

¿Alguien puede hacer que este código se ejecute y asegurarse de que todos los elementos se guardan en la base de datos?


Prueba el siguiente código en tu pipeline

import sys import MySQLdb import hashlib from scrapy.exceptions import DropItem from scrapy.http import Request class MySQLStorePipeline(object): def __init__(self): self.conn = MySQLdb.connect(''host'', ''user'', ''passwd'', ''dbname'', charset="utf8", use_unicode=True) self.cursor = self.conn.cursor() def process_item(self, item, spider): try: self.cursor.execute("""INSERT INTO example_book_store (book_name, price) VALUES (%s, %s)""", (item[''book_name''].encode(''utf-8''), item[''price''].encode(''utf-8''))) self.conn.commit() except MySQLdb.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]) return item


Su método process_item se debe declarar como: def process_item(self, item, spider): lugar de def process_item(self, spider, item): -> cambió los argumentos.

Esta excepción: exceptions.NameError: global name ''Exampleitem'' is not defined indica que no importó el Exampleitem a su canalización. Intente agregar: from myspiders.myitems import Exampleitem (con nombres / rutas correctas por supuesto).