最近,我不得不抓取更多的数据,并从使用提要格式'json‘改为’jsonline‘,以避免所有的数据都被搅乱和复制。问题是,现在我的程序中没有一个程序将导出的文件识别为JSON,因为它删除了每个项之后的开头和结尾方括号以及逗号。第一个例子显示了数据的样子,第二个例子显示了我想要实现的目标。
{"name": "Color TV", "price": "1200"}
{"name": "DVD player", "price": "200"}
---------------------------------------
{"data" : [
{"name": "Color TV", "price": "1200"},
{"name": "DVD player", "price": "200"},
{"name": "Color TV", "price": "1200"}
]}是否有一种在仍然使用JsonLinesItemExporter时手动添加逗号并使其成为数组的方法?
我想我的爬虫中唯一的代码是我的产关键字,但是我很乐意展示完整的代码。我不使用PHP或MySQL。
先谢谢你。
yield {
"name": name,
"old_price": old_price,
"discount_price": discount_price
}发布于 2018-03-20 20:28:50
首先是逗号。
最好的解决方案是包装JsonLinesItemExporter,以便在每一项的末尾添加一个逗号。
如果没有以覆盖、super和添加逗号的方式公开适当的方法,则可能必须在子类中重新实现该方法,甚至还必须在导出类中设置猴键。不太好。
或者,您可以将传递给导出程序的文件挂钩,使写操作成为replace('\n', ',\n')。这太麻烦了,所以如果你能让出口商上钩的话,我不会这么做,但它确实有一个简单的优点。
现在,文件开始和结束时的括号。如果不知道您使用的库或使用它的方式,这将是相当模糊的。
如果您在每个文件中使用导出程序的单个“会话”--也就是说,在启动时打开它,向它写一堆项目,然后关闭它,永远不要重新打开它并附加到它,这是非常容易的。让我们假设您通过子类导出类来挂钩它的写,从而解决了第一个问题,如下所示:
class JsonArrayExporter(JsonLinesItemExporter):
def _write_bytes(self, encoded_bytes):
encoded_bytes = _encoded_bytes.replace(b'\n', b',\n')
returns super()._write_bytes(encoded_bytes)我猜实现是什么样的,但是您已经发现了要做的正确的事情,所以您应该能够从我的猜测转换为现实。现在,您需要添加两个这样的方法:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._writebytes(b'[\n')
def close(self):
if not self.closed():
self._writebytes(b']\n')
super().close()如果导出类中有自己的缓冲区,那么在_writebytes之前可能需要一个_writebytes,但这是我希望看到的唯一额外的复杂性。
如果您要重新打开文件并在每个会话中附加它们,这显然是行不通的。您可以在__init__中执行类似于伪代码的操作
if file is empty:
write('[\n')
else:
seek to end of file
if last two bytes are ']\n':
seek back 2 bytes这具有对客户端代码透明的优点,但有点麻烦。如果客户端代码知道何时打开新文件,而不是附加到旧文件,并且知道何时会永久结束文件,那么添加addStartMarker和addEndMarker方法并调用这些方法,或者让客户端在初始化/关闭导出程序之后手动将方括号写入文件中,可能会更干净。
https://stackoverflow.com/questions/49391892
复制相似问题