Scrapy Spider для экспорта данных schema.org из нескольких URL в .csv - PullRequest
0 голосов
/ 24 августа 2018

Я пытаюсь создать паука, который будет сканировать список страниц (содержащихся в "initial_urls"), который будет извлекать данные schema.org и аккуратно экспортировать их в файл .csv - по одной строке на URL с 5 каждый столбец: url, business_name, address1, address2 и phone. Это мой текущий код для паука:

# -*- coding: utf-8 -*-
import scrapy
from schemaSpider.items import SchemaspiderItem


class SchemaSpider(scrapy.Spider):
    name = 'schema'
    start_urls = [
        'http://www.michaelangelosevents.com/',
    ]


def parse(self, response):
    import js2xml
    js_code = response.xpath("//script[contains(., 'address')]/text()").extract_first()
    parsed_js = js2xml.parse(js_code)
    js_sel = scrapy.Selector(root=parsed_js)
    addressTitle = js_sel.xpath("//property[@name='addressTitle']/string/text()").extract_first()
    addressLine1 = js_sel.xpath("//property[@name='addressLine1']/string/text()").extract_first()
    addressLine2 = js_sel.xpath("//property[@name='addressLine2']/string/text()").extract_first()
    contactPhoneNumber = js_sel.xpath("//property[@name='contactPhoneNumber']/string/text()").extract_first()
    item = ContactInfo()
    item['addressTitle'] = addressTitle
    item['addressLine1'] = addressLine1
    item['addressLine2'] = addressLine2
    item['phone'] = contactPhoneNumber
    yield item

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

Несмотря на то, что я вижу, что элемент распаковывает правильные данные при печати на стандартный вывод, он по какой-то причине не экспортирует. вот мой код pipelines.py:

import json                                                                                                                                                                                          
from scrapy.exporters import CsvItemExporter                                                                                                                                                         
import csv                                                                                                                                                                                                                                                                                                                                                                                                

class CsvPipeline(object):                                                                                                                                                                               

    def __init__(self):                                                                                                                                                                                      
        self.file = open("schemaInfo.csv", 'wb')                                                                                                                                                             
        self.exporter = CsvItemExporter(self.file, fields_to_export = 
        ['url','business_name','address1','address2','phone'])                                                                                 
        self.exporter.start_exporting()                                                                                                                                                                                                                                                                                                                                                                       

    def close_spider(self, spider):                                                                                                                                                                          
        self.exporter.finish_exporting()                                                                                                                                                                     
        self.file.close()                                                                                                                                                                                                                                                                                                                                                                                     
        def process_item(self, item, spider):                                                                                                                                                                    
        self.exporter.export_item(item)                                                                                                                                                                      
        return item     

class SchemaspiderPipeline(object):   

    def open_spider(self, spider):                                                                                                                                                                           
        self.file = open('items.jl', 'w')                                                                                                                                                                                                                                                                                                                                                                     

    def close_spider(self, spider):                                                                                                                                                                          
        self.file.close()                                                                                                                                                                                                                                                                                                                                                                                     
        def process_item(self, item, spider):                                                                                                                                                                    
        line = json.dumps(dict(item)) + "/n"                                                                                                                                                                 
        self.file.write(line)                                                                                                                                                                                
        yield item

Меня не очень интересует экспортер json - этот класс, по сути, является артефактом моих попыток получить что-то для экспорта. (оба конвейера включены, но я попытался сделать это с отключенным или обоими отключенными и используя только экспорт каналов).

Вот мои items.py:

import scrapy    

class SchemaspiderItem(scrapy.Item):                                                                                                                                                                     
    url = scrapy.Field()                                                                                                                                                                                 
    business_name = scrapy.Field()                                                                                                                                                                       
    address1 = scrapy.Field()                                                                                                                                                                            
    address2 = scrapy.Field()                                                                                                                                                                            
    phone = scrapy.Field()  

И (извините за натиск кода!), Вот моя последняя попытка реструктурировать вышеприведенный паук (первый блок кода) во что-то, что на самом деле будет экспортировать что-то:

import scrapy                                                                                                                                                                                        
from scrapy.http import Request                                                                                                                                                                      
import js2xml                                                                                                                                                                                        
from schemaSpider.items import SchemaspiderItem                                                                                                                                                                                                                                                                                                                                                           

class SchemaspiderItem(scrapy.Item):                                                                                                                                                                     
    business_name = scrapy.Field()                                                                                                                                                                       
    address1 = scrapy.Field()                                                                                                                                                                            
    address2 = scrapy.Field()                                                                                                                                                                            
    phone = scrapy.Field()                                                                                                                                                                               
    url = scrapy.Field()                                                                                                                                                                                                                                                                                                                                                                                  

class SchemaSpider(scrapy.Spider):                                                                                                                                                                       
    name = 'schema'                                                                                                                                                                                      
    start_urls = [                                                                                                                                                                                           
        'http://www.michaelangelosevents.com/'                                                                                                                                                           
        ]                                                                                                                                                                                                                                                                                                                                                                                                         

def parse(self, response):                                                                                                                                                                               
    js_code = response.xpath("//script[contains(., 
    'address')]/text()").extract_first()                                                                                                                                          
    for code in js_code:                                                                                                                                                                                     
        yield scrapy.Request(code, callback=self.parse_js)                                                                                                                                                                                                                                                                                                                                                

def parse_js(self, response):                                                                                                                                                                            
    parsed_js = js2xml.parse(js_code)                                                                                                                                                                    
    for js in parsed_js:                                                                                                                                                                                     
        yield scrapy.Request(js, callback=self.parse_contactInfo)                                                                                                                                                                                                                                                                                                                                         

def parse_contactInfo(self, response):                                                                                                                                                                   
    js_sel = scrapy.Selector(root=parsed_js)                                                                                                                                                             
        item = SchemaspiderItem()                                                                                                                                                                            
        item['url'] = start_url                                                                                                                                                                              
        item['business_name'] = js_sel.xpath("//property[@name='addressTitle']/string/text()").extract()                                                                                                     
        item['address1'] = js_sel.xpath("//property[@name='addressLine1']/string/text()").extract()                                                                                                          
        item['address2'] = js_sel.xpath("//property[@name='addressLine2']/string/text()").extract()                                                                                                          
        item['contactPhoneNumber'] = js_sel.xpath("//property[@name='contactPhoneNumber']/string/text()").extract()                                                                                          
        yield item  

Я просмотрел несколько других вопросов и ответов на этом сайте, касающихся использования скрапа и проблем с экспортом. Некоторые из них показались мне полезными, и я попробовал варианты этих решений, но безрезультатно! лучшее, что я получаю, это запятая под правильными заголовками в файле .csv (от первого паука вверху).

Любая помощь будет оценена! Спасибо! (также это мой первый пост здесь!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...