python - 将数组转换为 CSV,包括多行图像

标签 python csv shopify json2csv

我正在将数组转换为 csv,以便我可以快速将商品导入 Shopify。 According to Shopify ,您必须执行以下操作才能在导入时添加多张图片:

  1. 插入新行(每张图片一行)。
  2. 复制并粘贴“句柄”。
  3. 复制并粘贴图片网址。

因此,第一张图片排在第一行,所有后续图片排在下面几行。 CSV 示例位于此处:https://help.shopify.com/csv/product_template.csv

因此,我想编写一些程序来循环遍历数组,如下所示(除了明显更长),并将其转换为 CSV,将除第一张照片之外的所有照片放入新行。

var array = [
  {
    "brief": "Brief 1",
    "description": "Description 1",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010"
    ],
    "price": "145",
    "tags": [
      "tag1",
      "tag2",
      "tag3"
    ],
    "title": "Title 1"
  },
  {
    "brief": "Brief 2",
    "description": "Description 2",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010"
    ],
    "price": "150",
    "tags": [
      "tag4",
      "tag5",
      "tag6",
      "tag7",
      "tag8",
    ],
    "title": "Title 2"
  }
]

我通常用 json2csv 做这种事情,看起来像下面这样,只是我不确定如何处理多行方面。

json2csv -i data_in.json -f title,description,price,etc -o data_out.csv

Python 也可能是一个不错的选择,如下所示 this post ,但多行方面再次令人困惑:

import csv
import json

x = """[
  {
    "brief": "Brief 1",
    "description": "Description 1",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010"
    ],
    "price": "145",
    "tags": [
      "tag1",
      "tag2",
      "tag3"
    ],
    "title": "Title 1"
  },
  {
    "brief": "Brief 2",
    "description": "Description 2",
    "photos": [
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010",
      "https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010"
    ],
    "price": "150",
    "tags": [
      "tag4",
      "tag5",
      "tag6",
      "tag7",
      "tag8",
    ],
    "title": "Title 2"
  }
]"""

x = json.loads(x)

f = csv.writer(open("example.csv", "wb+"))

# Write CSV Header, If you dont need that, remove this line
f.writerow(["title", "description", "price"])

for x in x:
    f.writerow([x["title"],
                x["description"],
                x["price"])

CSV 的输出行顶部如下(必须“运行代码段”才能看到表格)- 请注意我不是要创建 HTML 表格:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:black;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:black;}
.tg .tg-yw4l{vertical-align:top}
</style>
<table class="tg">
  <tr>
    <th class="tg-yw4l">Handle</th>
    <th class="tg-yw4l">Title</th>
    <th class="tg-yw4l">Body (HTML)</th>
    <th class="tg-yw4l">Vendor</th>
    <th class="tg-yw4l">Type</th>
    <th class="tg-yw4l">Tags</th>
    <th class="tg-yw4l">Published</th>
    <th class="tg-yw4l">Option1 Name</th>
    <th class="tg-yw4l">Option1 Value</th>
    <th class="tg-yw4l">Option2 Name</th>
    <th class="tg-yw4l">Option2 Value</th>
    <th class="tg-yw4l">Option3 Name</th>
    <th class="tg-yw4l">Option3 Value</th>
    <th class="tg-yw4l">Variant SKU</th>
    <th class="tg-yw4l">Variant Grams</th>
    <th class="tg-yw4l">Variant Inventory Tracker</th>
    <th class="tg-yw4l">Variant Inventory Qty</th>
    <th class="tg-yw4l">Variant Inventory Policy</th>
    <th class="tg-yw4l">Variant Fulfillment Service</th>
    <th class="tg-yw4l">Variant Price</th>
    <th class="tg-yw4l">Variant Compare At Price</th>
    <th class="tg-yw4l">Variant Requires Shipping</th>
    <th class="tg-yw4l">Variant Taxable</th>
    <th class="tg-yw4l">Variant Barcode</th>
    <th class="tg-yw4l">Image Src</th>
    <th class="tg-yw4l">Image Alt Text</th>
    <th class="tg-yw4l">Gift Card</th>
    <th class="tg-yw4l">Google Shopping / MPN</th>
    <th class="tg-yw4l">Google Shopping / Age Group</th>
    <th class="tg-yw4l">Google Shopping / Gender</th>
    <th class="tg-yw4l">Google Shopping / Google Product Category</th>
    <th class="tg-yw4l">SEO Title</th>
    <th class="tg-yw4l">SEO Description</th>
    <th class="tg-yw4l">Google Shopping / AdWords Grouping</th>
    <th class="tg-yw4l">Google Shopping / AdWords Labels</th>
    <th class="tg-yw4l">Google Shopping / Condition</th>
    <th class="tg-yw4l">Google Shopping / Custom Product</th>
    <th class="tg-yw4l">Google Shopping / Custom Label 0</th>
    <th class="tg-yw4l">Google Shopping / Custom Label 1</th>
    <th class="tg-yw4l">Google Shopping / Custom Label 2</th>
    <th class="tg-yw4l">Google Shopping / Custom Label 3</th>
    <th class="tg-yw4l">Google Shopping / Custom Label 4</th>
    <th class="tg-yw4l">Variant Image</th>
    <th class="tg-yw4l">Variant Weight Unit</th>
    <th class="tg-yw4l"></th>
    <th class="tg-yw4l"></th>
  </tr>
  <tr>
    <td class="tg-yw4l">Title 1</td>
    <td class="tg-yw4l">Title 1</td>
    <td class="tg-yw4l">Description 1</td>
    <td class="tg-yw4l">Vendor Name</td>
    <td class="tg-yw4l">Product Type</td>
    <td class="tg-yw4l">"tag1,tag2,tag3"</td>
    <td class="tg-yw4l">TRUE</td>
    <td class="tg-yw4l">Title 1</td>
    <td class="tg-yw4l">Default Title</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l">1</td>
    <td class="tg-yw4l">deny</td>
    <td class="tg-yw4l">manual</td>
    <td class="tg-yw4l">145</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l">TRUE</td>
    <td class="tg-yw4l">TRUE</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l">https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">Title 1</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l">https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
  <tr>
    <td class="tg-yw4l">Title 1</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l">https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010</td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
    <td class="tg-yw4l"></td>
  </tr>
</table>

最佳答案

这不是特别难。您的代码几乎是正确的(假设列的布局是您想要的,并且假设您传递了有效的 JSON,因为您的代码有一个额外的逗号),您只需要添加一点:

for x in x:
    images = x["photos"]
    f.writerow([x["title"],
                x["description"],
                x["price"],
                images.pop(0) if images else None])
    while images:
        f.writerow([None, None, None, images.pop(0)])

简而言之,它的作用是按顺序遍历所有图像,并将它们打印在新的、否则为空的行中。在您的原始代码上运行它,example.csv 最终看起来像这样:

title,description,price
Title 1,Description 1,145,https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example.jpg?0101010101010
,,,https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example2.jpg?0101010101010
,,,https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example3.jpg?0101010101010
Title 2,Description 2,150,https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example4.jpg?0101010101010
,,,https://cdn.shopify.com/s/files/1/01/01/01/files/imgs-example5.jpg?0101010101010

如何将内容放入不同的列应该是非常明显的——None 只是为了让 csv.writer 将单元格留空,所以将它们用作所有其他列的占位符。

如果这需要易于修改,我会推荐一种不同的方法。不过,这看起来像是一次性转换脚本,因此快速、简单的破解就可以了。

一些注意事项:

  • a if b else c,如果b的计算结果为True,表示a;如果计算结果为 False,则表示 c
  • ary.pop(n)ary 中弹出(删除并返回)索引为 n 的对象。
  • 空数组的计算结果为 False(因此我只测试 images,而不是 len(images) == 0)
  • 您可能还想更新 header 。我只是按原样处理它们,所以我唯一的更改是对最后一个 while;您可能希望修复它们以准确标记列。

关于python - 将数组转换为 CSV,包括多行图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51214273/

相关文章:

python - 使用 seaborn 对 python 中的 matplotlib 进行核密度估计的下限

python - 无法使用 databricks-connect "V2"V.13.2 访问 databricks 集群

python - 如何使用 ClientCredentialFlow 授权 MS Project ODATA API?

python - 搜索 csv 文件中的列

javascript - 时事通讯弹出窗口中的 Cookie 重置时间

javascript - 适合库存的 Shopify 数量下拉列表

python - 如何从EXE中提取32x32图标位图数据并将其转换为PIL Image对象?

sql - PSQL 选择以逗号分隔的结果加入连接

python - CSV、Python 中的字符串大小写运算

php - 使用 https ://{shop}. myshopify.com/admin/oauth/access_token 时,Shopify 出现错误 400 [Bad Request]