Загрузка Scrapy не загружает всю информацию в postgres.Зачем? - PullRequest
0 голосов
/ 10 июля 2019

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

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

quotes_spider.py

import scrapy
from ..items import TutorialItem

class QuoteSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = [
        'https://campustechnology.com/articles/list/news.aspx'
    ]

    def parse(self, response):

        items = TutorialItem()

        title = response.css('.title a::text').extract()
        author = response.css('.summary::text').extract()
        date = response.css('.nodate::text').extract()
        urls = response.css('.title a').xpath("@href").extract()

        items["title"] = title
        items["author"] = author
        items["date"] = date
        items["urls"] = urls
        yield items

pipelines.py

import psycopg2


class TutorialPipeline(object):

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

    def create_connection(self):
        self.conn = psycopg2.connect(
            "host=pellefant.db.elephantsql.com dbname=x user=x 
             password=x"
        )
        self.cur = self.conn.cursor()

    def create_table(self):
        self.cur.execute("drop table if exists quotes_tb;")
        self.cur.execute('''
             create table quotes_tb(
               title varchar(255),
               author varchar(255),
               date varchar(255),
               urls varchar(255)
               )
        ''')

    def process_item(self, item, spider):
        self.store_db(item)
        return item

    def store_db(self, item):
        self.cur.execute('''insert INTO quotes_tb (title, author, date, 
                          urls) VALUES (%s, %s, %s, %s)''', (
            item["title"][0],
            item["author"][0],
            item["date"][0],
            item["urls"][0]
        ))
        self.conn.commit()

Я ожидаю увидеть в моей базе данных список всей информации, разделенной строками. Не только первая собранная информация и одна строка.

1 Ответ

2 голосов
/ 10 июля 2019

Вы ставите только одну строку, потому что ставите item["title"][0], (и т. Д.), Но также могут быть item["title"][1] и item["title"][2] и т. Д.


Вы можете использовать for -loop с zip() для группировки элементов и вставки каждой строки отдельно

for row in zip(item["title"], item["author"], item["date"], item["urls"]):
     self.cur.execute('''insert INTO quotes_tb (title, author, date, urls) 
                           VALUES (%s, %s, %s, %s)''', row )

или сначала создайте все строки, а затем используйте только один запрос с execute_values()

all_rows = list( zip(item["title"], item["author"], item["date"], item["urls"]) )

self.cur.execute_values('''insert INTO quotes_tb (title, author, date, urls) 
                           VALUES (%s, %s, %s, %s)''',  all_rows)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...