scrapy到dataframe到csv?

时间:2018-03-07 15:58:45

标签: python pandas dataframe scrapy

我这里有一个scrapy代码输出一个json文件。然后我使用jupyter notebook将json文件导入数据帧以清理数据。但是,我真正想做的是能够运行scrapy spider并将数据输出为已经清理过的CSV,而不是将已删除的数据保存为json文件并进入jupyter笔记本来清理它。无论如何要连接这两个过程?下面是我的蜘蛛代码:

import scrapy
import pandas as pd
import json
import datetime
from seatgeek.items import SeatgeekItem

class seatgeekSpider(scrapy.Spider):
    name = "seatgeek_spider"
    #showname = input("Enter Show name (lower case please): ")
    #showname = showname.replace(' ', '-')
    start_urls = ["https://seatgeek.com/come-from-away-tickets?page={}".format(i) for i in range (1,35)]

    custom_settings = {
        'DOWNLOAD_DELAY': 3,
        'CONCURRENT_REQUESTS_PER_DOMAIN': 3,
        'HTTPCACHE_ENABLED': True,
        'FEED_FORMAT': 'json',
        'FEED_URI': 'test.json'
    }

    def parse(self, response):
        for href in response.xpath('//a[@class="event-listing-title"]/@href').extract():
            item = SeatgeekItem()
            item['performance'] = href.split('/')[-3]
            item["eventId"] = href.split('/')[-1]

            yield scrapy.Request(
                url = 'https://seatgeek.com/listings?id=' + item['eventId'] + '&aid=11955&client_id=MTY2MnwxMzgzMzIwMTU4',
                callback=self.parse_ticketinv,
                meta={'item': item})

    def parse_ticketinv(self, response):
        jsonresponse = json.loads(response.body_as_unicode())
        item = response.meta['item']
        for i in jsonresponse["listings"]:
            item["sectionName"] = i["s"]
            item["zoneName"] = i["s"].split(' ')[0]
            item["currentPrice"] = i["p"]
            item["listingPrice"] = i["p"]
            item["row"] = i["r"]
            item["seatNumbers"] = ""
            item['listingId'] = i["id"]
            item['quantity'] = i["q"]
            item['vendor'] = "SeatGeek"

            yield item

这是我清理数据的代码:

import json
import pandas as pd
import datetime

path = r'C:\Users\...\Desktop\Code\seatgeek\test.json'

with open(path) as f:
    data = json.load(f)

df = pd.DataFrame(data)

df = df[df.performance.str.contains('gerald')]
df['performance'] = df['performance'].map(lambda x: x.lstrip('gerald-schoenfeld-theatre-').rstrip('-pm'))
df['performance'] = df['performance'].apply(lambda x: datetime.datetime.strptime(x,'%Y-%m-%d-%H'))

df['datePulled'] = pd.to_datetime('today')

filename = input('Enter filename: ')
df.to_csv(filename + '.csv', mode='a', index=False)

修改

Per @stranac的帮助,我用下面的代码更新了我的管道。但是出于某种原因,我似乎丢失/我不想删除的一些行。好像我评论item['performance'] = datetime.datetime.strptime(item['performance'][26:],'%Y-%m-%d-%H-%p'),它会正常工作。

def process_item(self, item, spider):
   if 'gerald' not in item['performance']:
      raise DropItem
   item['performance'] = datetime.datetime.strptime(item['performance'][26:],'%Y-%m-%d-%H-%p')
   item['datePulled'] = datetime.datetime.now()
   return item

1 个答案:

答案 0 :(得分:1)

最简单的方法是编写自己的item pipeline,并在process_item()中对每个项目进行清理,而不是使用pandas一次完成所有操作。

class YourPipeline(object):
    def process_item(self, item, spider):
        if 'gerald' not in item['performance']:
            raise DropItem
        # do your cleanup
        return item

旁注:lstriprstrip不做你的想法,在这种情况下恰好会产生正确的结果。

编辑:

您获得的错误是由同一项目从parse_ticketinv多次产生的。 这会导致已修改的项目(item['performance']datetime对象替换)再次通过管道,从而导致TypeError

解决问题的最简单方法是在每个循环中创建一个新项目,或者产生项目副本:

def parse_ticketinv(self, response):
    # for whatever:
        # do stuff
        yield item.copy()