Écrire des articles dans une base de données MySQL à Scrapy

je suis nouveau sur Scrapy, j'ai eu l'araignée code

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

Et le pipeline de code est:

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)          

Après cela, j'obtiens l'erreur suivante

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

j'ai l'erreur ci-dessus lorsque j'ai ajouté le code ci-dessous dans process_item méthode

assert isinstance(item, Exampleitem)

et sans l'ajout de cette ligne, j'obtiens

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

est-ce que quelqu'un peut faire fonctionner ce code et s'assurer que tous les éléments sauvegardés dans la base de données?

19
demandé sur Do Nhu Vy 2012-06-01 11:03:37

3 réponses

Essayez le code suivant dans votre 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
33
répondu Mahmoud M. Abdel-Fattah 2018-04-04 11:33:36

votre méthode process_item doit être déclarée comme:def process_item(self, item, spider): au lieu de def process_item(self, spider, item): - > Vous avez changé les arguments.

Cette exception: exceptions.NameError: global name 'Exampleitem' is not defined indique que vous n'avez pas importé L'Exampleitem dans votre pipeline. Essayez d'ajouter: from myspiders.myitems import Exampleitem(avec les noms/chemins corrects de cours).

1
répondu Sjaak Trekhaak 2012-06-01 09:27:46

je pense que cette façon est la meilleure et la plus concise:

#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))

C'est comme

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

Cause (vous pouvez en lire plus à propos de Éléments dans Scrapy)

la classe Field n'est qu'un alias de la classe DCT intégrée et ne fournit aucune fonctionnalité ou attribut supplémentaire. En d'autres termes, les objets Field sont des dicts Python simples et vieux.

1
répondu FavorMylikes 2017-05-12 06:11:05