抓取使用项并将数据保存在json文件中

时间:2019-05-06 12:53:16

标签: python python-3.x web-scraping scrapy scrapy-item

我想使用临时项目并处理数据并将其全部保存在json文件中(使用db这样的json文件)。

# Spider Class

class Spider(scrapy.Spider):
    name = 'productpage'
    start_urls = ['https://www.productpage.com']

    def parse(self, response):
        for product in response.css('article'):

            link = product.css('a::attr(href)').get()
            id = link.split('/')[-1]
            title = product.css('a > span::attr(content)').get()
            product = Product(self.name, id, title, price,'', link)
            yield scrapy.Request('{}.json'.format(link), callback=self.parse_product, meta={'product': product})

        yield scrapy.Request(url=response.url, callback=self.parse, dont_filter=True)

    def parse_product(self, response):
        product = response.meta['product']
        for size in json.loads(response.body_as_unicode()):
            product.size.append(size['name'])

        if self.storage.update(product.__dict__):
            product.send('url')


# STORAGE CLASS

class Storage:

    def __init__(self, name):
        self.name = name
        self.path = '{}.json'.format(self.name)
        self.load()  """Load json database"""

    def update(self, new_item):
        # .... do things and update data ...
        return True

# Product Class

class Product:

    def __init__(self, name, id, title, size, link):
        self.name = name
        self.id = id
        self.title = title
        self.size = []
        self.link = link

    def send(self, url):
        return  # send notify...


蜘蛛类在start_url主页中搜索产品,然后解析产品页面以捕获尺寸。 最后,它搜索self.storage.update(product.__dict__)上是否有更新,如果是,则发送通知。

如何在代码中实现Item?我以为可以在产品类中插入它,但不能包含send方法...

2 个答案:

答案 0 :(得分:1)

您应该定义所需的项目。并在解析后yield

最后,运行命令: scrapy crawl [spider] -o xx.json

PS: 默认scrapy支持导出json文件。

答案 1 :(得分:0)

@Jadian的答案将为您提供一个带有JSON的文件,但与访问它的数据库并不完全相同。为了从设计角度正确执行此操作,我将遵循以下说明。您也不必使用mongo,也可以使用其他使用JSON的其他nosql数据库。

在这种情况下,我建议您使用scrapy.Item()类正确构建项。然后您可以使用json.dumps进入mongoDB。您将需要为每个项目分配一个PK,但是mongo基本上是一个非关系json存储。因此,您要做的就是创建一个项目管道,检查项目的PK,如果找到了项目的PK,并且没有更改任何细节,则引发DropItem(),否则将新数据更新/存储到mongodb中。如果可能,您甚至可以通过管道将其导入json导出器,但是我认为仅将python对象转储到json到mongo中是可行的方法,然后mongo会向您展示可在前端使用的json。

我希望您理解这个答案,但是我认为从设计的角度来看,这将是一个简单得多的解决方案,因为mongo基本上是基于JSON的非关系数据存储,并且您将项目管道逻辑划分为自己的项目而不是使蜘蛛杂乱无章。

我将提供一个代码示例,但是我的大多数人都将ORM用于SQL数据库。实际上,Mongo比这更易于使用...