recherche

Maison  >  Questions et réponses  >  le corps du texte

Scrapy INSERT dans 'new_table' uniquement si aucun enregistrement n'existe dans la 'table actuelle'

J'ai essayé du scraping de sites Web. J'ai réussi à récupérer les données de la table de base de données actuelle. Mais je veux insérer "new_table" uniquement si l'enregistrement n'existe pas dans la "table actuelle"

Mon code est (pipeline)

table = 'products'
table2 = 'new_products'`
def save(self, row): 

    
    cursor = self.cnx.cursor()
    cursor.execute("SELECT DISTINCT product_id FROM products;")
    old_ids = [row[0] for row in cursor.fetchall()]
    create_query = ("INSERT INTO " + self.table + 
        "(rowid, date, listing_id, product_id, product_name, price, url) "
        "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s)")

    cursor.execute(create_query, row)
    lastRecordId = cursor.lastrowid

    self.cnx.commit()
    cursor.close()
    print("Item saved with ID: {}" . format(lastRecordId))

    if not product_id in old_ids:
        create_query = ("INSERT INTO " + self.table2 + 
            "(rowid, date, listing_id, product_id, product_name, price, url) "
            "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s)")

Cela ne fonctionne pas correctement et il y a une erreur.

2022-05-06 12:26:57 [scrapy.core.scraper] ERROR: Error processing {'date': '2022-05-06 12:26:57.575507',
 'listing_id': '0190199600119',
 'price': '4199.00',
 'product_id': '1209298',
 'product_name': 'APPLE 11" Magic Türkçe Q Klavye Siyah',
 'rowid': 456274953331128512,
 'url': 'https://www.mediamarkt.com.tr/tr/product/APPLE%2011%22%20Magic%20T%C3%BCrk%C3%A7e%20Q%20Klavye%20Siyah-1209298.html'}
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/twisted/internet/defer.py", line 654, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/usr/local/lib/python3.8/dist-packages/scrapy/utils/defer.py", line 162, in f
    return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
  File "/root/teknosa/teknosa/pipelines.py", line 28, in process_item
    self.save(dict(item))
  File "/root/teknosa/teknosa/pipelines.py", line 62, in save
    if not product_id in old_ids:
NameError: name 'product_id' is not defined
Saving item into db ...

J'ai un product_id unique.

S'il n'y a pas de product_id dans la table actuelle, insérez ce product_id dans "new_products"

Comment faire ça ?

Merci.

Dernière modification : j'obtiens cette erreur.

2022-05-07 18:17:11 [scrapy.core.scraper] ERROR: Error processing {'date': '2022-05-07 18:17:11.902622',
 'listing_id': '8713439219357',
 'price': '99.00',
 'product_id': '1175529',
 'product_name': 'TRUST 21935 NANGA USB 3.1 Kart Okuyucu',
 'rowid': -411152717288573423,
 'url': 'https://www.mediamarkt.com.tr/tr/product/TRUST%2021935%20NANGA%20USB%203.1%20Kart%20Okuyucu-1175529.html'}
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 523, in cmd_query
    self._cmysql.query(query,
_mysql_connector.MySQLInterfaceError: Duplicate entry '-411152717288573423' for key 'products.rowid'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/twisted/internet/defer.py", line 654, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/usr/local/lib/python3.8/dist-packages/scrapy/utils/defer.py", line 162, in f
    return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
  File "/root/teknosa/teknosa/pipelines.py", line 28, in process_item
    self.save(dict(item))
  File "/root/teknosa/teknosa/pipelines.py", line 69, in save
    cursor.execute(create_query, row)
  File "/usr/local/lib/python3.8/dist-packages/mysql/connector/cursor_cext.py", line 269, in execute
    result = self._cnx.cmd_query(stmt, raw=self._raw,
  File "/usr/local/lib/python3.8/dist-packages/mysql/connector/connection_cext.py", line 528, in cmd_query
    raise errors.get_mysql_exception(exc.errno, msg=exc.msg,
mysql.connector.errors.IntegrityError: 1062 (23000): Duplicate entry '-411152717288573423' for key 'products.rowid'

P粉122932466P粉122932466272 Il y a quelques jours400

répondre à tous(1)je répondrai

  • P粉278379495

    P粉2783794952024-03-30 00:30:37

    Si vous souhaitez simplement insérer s'il n'existe pas, vous n'avez pas besoin de faire ce que vous faites. Pas besoin de tous les sélectionner et de voir si celui que vous recherchez est là.

    Ce dont vous avez besoin est de créer un index unique pour le produc_id

    dans le tableau 2

    Puis changez le code en :

    table = 'products'
    table2 = 'new_products'`
    
    def save(self, row):  
        create_query = ("INSERT INTO " + self.table + 
            "(rowid, date, listing_id, product_id, product_name, price, url) "
            "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s)")
    
        cursor.execute(create_query, row)
        lastRecordId = cursor.lastrowid
    
        self.cnx.commit()
        print("Item saved with ID: {}" . format(lastRecordId))
        create_query = ("INSERT INTO " + self.table2 + 
                "(rowid, date, listing_id, product_id, product_name, price, url) "
                "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s) ON DUPLICATE KEY UPDATE product_id=product_id")
        cursor.execute(create_query, row)
        self.cnx.commit()

    Si vous utilisez ON DUPLICATE KEY, lorsqu'il trouve une ligne en double (product_id déjà existant), le système essaiera de mettre à jour le product_id avec le même product_id, donc cela ne prendra pas effet.

    Si vous définissez autocommit=True, vous pouvez supprimer ces commits.

    Modifier

    Si, comme vous l'avez dit dans votre commentaire, vous devez insérer dans le nouveau tableau uniquement s'il n'existe pas dans le tableau, vous pouvez modifier votre code comme ceci :

    Vous devez changer le nom de la variable dans la ligne old_ids = [row[0] pour la ligne incursor.fetchall()] car vous modifiez la valeur du paramètre row 2. Votre problème réside dans l'instruction if, la variable product_id n'existe pas et doit être modifiée

    table = 'products'
    table2 = 'new_products'`
    
    def save(self, row):     
        cursor = self.cnx.cursor()
        cursor.execute("SELECT DISTINCT product_id FROM products;")
        old_ids = [element[0] for element in cursor.fetchall()]
        create_query = ("INSERT INTO " + self.table + 
            "(rowid, date, listing_id, product_id, product_name, price, url) "
            "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s)")
    
        cursor.execute(create_query, row)
        lastRecordId = cursor.lastrowid
    
        self.cnx.commit()
        cursor.close()
        print("Item saved with ID: {}" . format(lastRecordId))
    
     
    
       if not row['product_id'] in old_ids:
            create_query = ("INSERT INTO " + self.table2 + 
                "(rowid, date, listing_id, product_id, product_name, price, url) "
                "VALUES (%(rowid)s, %(date)s, %(listing_id)s, %(product_id)s, %(product_name)s, %(price)s, %(url)s)")

    répondre
    0
  • Annulerrépondre