Выход Scrapy до MySql на одной линии - PullRequest
0 голосов
/ 15 марта 2020

У меня проблемы с получением scrap для вывода результатов на нескольких строках в моей базе данных. Я знаю, как получить его в l oop, когда я экспортирую в файл json, но, так как я новичок с лукавством, я следовал некоторым учебникам по синтаксису для экспорта в базу данных, но он помещает возвращаемые данные в одну строку , Вот мой код для паука

import scrapy


from ..items import SandboxItem
class IndigoSpider(scrapy.Spider):
    name = 'Indigo'
    start_urls = ['https://www.chapters.indigo.ca/en-ca/books/?link-usage=Header%3A%20books&mc=Book&lu=Main']


def parse(self, response):
    items = SandboxItem()
    Product_Name= str(response.css('.product-list__product-title-link--grid::text').getall()),
    Product_Author= str(response.css('.product-list__contributor::text').getall()),
    Product_Price= str(response.css('.product-list__price--orange::text').getall()),
    Product_Image=  str(response.css('.product-image--lazy::attr(src)').getall())

    items['Product_Name'] = Product_Name
    items['Product_Author'] = Product_Author
    items['Product_Price'] = Product_Price
    items['Product_Image'] = Product_Image

    yield items

Вот мой код для моего конвейера

import mysql.connector

class SandboxPipeline(object):


    def __init__(self):
        self.create_connection()
        self.create_table()
        # pass

    def create_connection(self):
        self.conn = mysql.connector.connect(
            host='localhost',  
            user='root',
            passwd='test123',
            database='python',
            auth_plugin='mysql_native_password'
        )
        self.curr = self.conn.cursor()

    def create_table(self):
        self.curr.execute(""" DROP TABLE IF EXISTS indigo""")
        self.curr.execute(""" Create table indigo(
        Product_Name text,
        Product_Author text,
        Product_Price text,
        Product_Image text
        )""")

    def process_item(self, item, spider):
        self.store_db(item)
        #     print("pipelinexds:" + str(item['Product_Name']))
        #     print(str(item['Product_Name']))
        return item

    #
    def store_db(self, item):
        self.curr.execute("""Insert Into indigo values (%s,%s,%s,%s)""",
                          ((item['Product_Name'][0]),
                           (item['Product_Author'][0]),
                           (item['Product_Price'][0]),
                           (item['Product_Image'][0]),
                           )
                          )
        self.conn.commit()

Вывод базы данных выглядит следующим образом .

1 Ответ

0 голосов
/ 15 марта 2020

Похоже, ваш item действительно содержит несколько предметов. Поэтому вам нужно включить for l oop где-нибудь, чтобы изменить архитектуру программы.

Я бы предложил использовать что-то вроде:

for i in len(Product_Name):
    yield  {
        'Product_Name': Product_Name[i],
        'Product_Author': Product_Author[i],
        'Product_Price': Product_Price[i],
        'Product_Image': Product_Image[i]
    }

Таким образом, элемент будет содержать одно значение , Это должно быть обработано правильно.

def parse(self, response):
    items = SandboxItem()
    Product_Name= str(response.css('.product-list__product-title-link--grid::text').getall()),
    Product_Author= str(response.css('.product-list__contributor::text').getall()),
    Product_Price= str(response.css('.product-list__price--orange::text').getall()),
    Product_Image=  str(response.css('.product-image--lazy::attr(src)').getall())

    for i in len(Product_Name):
        yield  {
            'Product_Name': Product_Name[i],
            'Product_Author': Product_Author[i],
            'Product_Price': Product_Price[i],
            'Product_Image': Product_Image[i]
        }

...