Files
F6--/张阳脚本/竞品系统数据导出/有礼云数据导出.ipynb
T
2026-01-30 11:28:35 +08:00

1225 lines
64 KiB
Plaintext

{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "## 车辆信息导出",
"id": "49132812ce220785"
},
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2025-04-08T07:16:21.815228Z",
"start_time": "2025-04-08T07:07:47.712264Z"
}
},
"source": [
"import time\n",
"\n",
"import requests\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"\n",
"url = 'https://www.4008778515.com/Carsinfo/getAllCarinfoList2'\n",
"headers = {\n",
" \"authority\": \"www.4008778515.com\",\n",
" \"method\": \"POST\",\n",
" \"path\": \"/Carsinfo/getAllCarinfoList2\",\n",
" \"scheme\": \"https\",\n",
" \"accept\": \"application/json, text/javascript, */*; q=0.01\",\n",
" \"accept-encoding\": \"gzip, deflate, br, zstd\",\n",
" \"accept-language\": \"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\",\n",
" \"content-length\": \"2422\",\n",
" \"content-type\": \"application/x-www-form-urlencoded; charset=UTF-8\",\n",
" \"cookie\": \"PHPSESSID=7btmjj5l56o3sfqcllv5h3eqs0; Hm_lvt_15244cf00ec0dd2686e4c0e425aecdd5=1743990464; HMACCOUNT=ABFCA62083E00432; Hm_lpvt_15244cf00ec0dd2686e4c0e425aecdd5=1743991434\",\n",
" \"origin\": \"https://www.4008778515.com\",\n",
" \"priority\": \"u=1, i\",\n",
" \"referer\": \"https://www.4008778515.com/index.php/Carsinfo/index\",\n",
" \"sec-ch-ua\": '\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Microsoft Edge\";v=\"134\"',\n",
" \"sec-ch-ua-mobile\": \"?0\",\n",
" \"sec-ch-ua-platform\": '\"Windows\"',\n",
" \"sec-fetch-dest\": \"empty\",\n",
" \"sec-fetch-mode\": \"cors\",\n",
" \"sec-fetch-site\": \"same-origin\",\n",
" \"user-agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0\",\n",
" \"x-requested-with\": \"XMLHttpRequest\"\n",
"}\n",
"all_data = []\n",
"\n",
"for i in tqdm(range(0, 440)):\n",
" data = {\n",
" \"draw\": \"4\",\n",
" \"columns[0][data]\": \"Codes\",\n",
" \"columns[0][name]\": \"\",\n",
" \"columns[0][searchable]\": \"true\",\n",
" \"columns[0][orderable]\": \"false\",\n",
" \"columns[0][search][value]\": \"\",\n",
" \"columns[0][search][regex]\": \"false\",\n",
" \"columns[1][data]\": \"MemberCard\",\n",
" \"columns[1][name]\": \"\",\n",
" \"columns[1][searchable]\": \"true\",\n",
" \"columns[1][orderable]\": \"false\",\n",
" \"columns[1][search][value]\": \"\",\n",
" \"columns[1][search][regex]\": \"false\",\n",
" \"columns[2][data]\": \"Name\",\n",
" \"columns[2][name]\": \"\",\n",
" \"columns[2][searchable]\": \"true\",\n",
" \"columns[2][orderable]\": \"false\",\n",
" \"columns[2][search][value]\": \"\",\n",
" \"columns[2][search][regex]\": \"false\",\n",
" \"columns[3][data]\": \"RegistrationNum\",\n",
" \"columns[3][name]\": \"\",\n",
" \"columns[3][searchable]\": \"true\",\n",
" \"columns[3][orderable]\": \"false\",\n",
" \"columns[3][search][value]\": \"\",\n",
" \"columns[3][search][regex]\": \"false\",\n",
" \"columns[4][data]\": \"CarBrand\",\n",
" \"columns[4][name]\": \"\",\n",
" \"columns[4][searchable]\": \"true\",\n",
" \"columns[4][orderable]\": \"false\",\n",
" \"columns[4][search][value]\": \"\",\n",
" \"columns[4][search][regex]\": \"false\",\n",
" \"columns[5][data]\": \"Phone\",\n",
" \"columns[5][name]\": \"\",\n",
" \"columns[5][searchable]\": \"true\",\n",
" \"columns[5][orderable]\": \"false\",\n",
" \"columns[5][search][value]\": \"\",\n",
" \"columns[5][search][regex]\": \"false\",\n",
" \"columns[6][data]\": \"Balance\",\n",
" \"columns[6][name]\": \"\",\n",
" \"columns[6][searchable]\": \"true\",\n",
" \"columns[6][orderable]\": \"false\",\n",
" \"columns[6][search][value]\": \"\",\n",
" \"columns[6][search][regex]\": \"false\",\n",
" \"columns[7][data]\": \"ChainShopName\",\n",
" \"columns[7][name]\": \"\",\n",
" \"columns[7][searchable]\": \"true\",\n",
" \"columns[7][orderable]\": \"false\",\n",
" \"columns[7][search][value]\": \"\",\n",
" \"columns[7][search][regex]\": \"false\",\n",
" \"columns[8][data]\": \"CCreatetime\",\n",
" \"columns[8][name]\": \"\",\n",
" \"columns[8][searchable]\": \"true\",\n",
" \"columns[8][orderable]\": \"false\",\n",
" \"columns[8][search][value]\": \"\",\n",
" \"columns[8][search][regex]\": \"false\",\n",
" \"columns[9][data]\": \"MemberID\",\n",
" \"columns[9][name]\": \"\",\n",
" \"columns[9][searchable]\": \"true\",\n",
" \"columns[9][orderable]\": \"false\",\n",
" \"columns[9][search][value]\": \"\",\n",
" \"columns[9][search][regex]\": \"false\",\n",
" \"order[0][column]\": \"0\",\n",
" \"order[0][dir]\": \"desc\",\n",
" \"start\": 10 * i,\n",
" \"length\": \"10\",\n",
" \"search[value]\": \"\",\n",
" \"search[regex]\": \"false\",\n",
" \"RankID\": \"0\",\n",
" \"MemberCardLevel\": \"1\",\n",
" \"IsCheckChainShop\": \"0\",\n",
" \"searchContent\": \"\",\n",
" \"search_type\": \"RegistrationNum\",\n",
" \"balance_state\": \"0\",\n",
" \"linkid\": \"feff91c6049983b9d8ca25d5c4590d08\"\n",
" }\n",
"\n",
" res = requests.post(url, headers=headers, data=data)\n",
" # print(res.json())\n",
" data_list = res.json().get('data')\n",
" if data_list:\n",
" for data in data_list:\n",
" all_data.append(data)\n",
" time.sleep(1)\n",
"\n",
"df = pd.DataFrame(all_data)\n",
"df.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云车辆信息.xlsx', index=False)"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 440/440 [08:32<00:00, 1.16s/it]\n"
]
},
{
"ename": "PermissionError",
"evalue": "[Errno 13] Permission denied: 'D:\\\\Idea Project\\\\F6+宜搭+其它(1)\\\\new\\\\文件输出\\\\有礼云车辆信息.xlsx'",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mPermissionError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[4], line 120\u001B[0m\n\u001B[0;32m 117\u001B[0m time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;241m1\u001B[39m)\n\u001B[0;32m 119\u001B[0m df \u001B[38;5;241m=\u001B[39m pd\u001B[38;5;241m.\u001B[39mDataFrame(all_data)\n\u001B[1;32m--> 120\u001B[0m df\u001B[38;5;241m.\u001B[39mto_excel(\u001B[38;5;124mr\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mD:\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mIdea Project\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mF6+宜搭+其它(1)\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124mnew\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m文件输出\u001B[39m\u001B[38;5;124m\\\u001B[39m\u001B[38;5;124m有礼云车辆信息.xlsx\u001B[39m\u001B[38;5;124m'\u001B[39m, index\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\util\\_decorators.py:333\u001B[0m, in \u001B[0;36mdeprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper\u001B[1;34m(*args, **kwargs)\u001B[0m\n\u001B[0;32m 327\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mlen\u001B[39m(args) \u001B[38;5;241m>\u001B[39m num_allow_args:\n\u001B[0;32m 328\u001B[0m warnings\u001B[38;5;241m.\u001B[39mwarn(\n\u001B[0;32m 329\u001B[0m msg\u001B[38;5;241m.\u001B[39mformat(arguments\u001B[38;5;241m=\u001B[39m_format_argument_list(allow_args)),\n\u001B[0;32m 330\u001B[0m \u001B[38;5;167;01mFutureWarning\u001B[39;00m,\n\u001B[0;32m 331\u001B[0m stacklevel\u001B[38;5;241m=\u001B[39mfind_stack_level(),\n\u001B[0;32m 332\u001B[0m )\n\u001B[1;32m--> 333\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m func(\u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\core\\generic.py:2417\u001B[0m, in \u001B[0;36mNDFrame.to_excel\u001B[1;34m(self, excel_writer, sheet_name, na_rep, float_format, columns, header, index, index_label, startrow, startcol, engine, merge_cells, inf_rep, freeze_panes, storage_options, engine_kwargs)\u001B[0m\n\u001B[0;32m 2404\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpandas\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mio\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mformats\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mexcel\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m ExcelFormatter\n\u001B[0;32m 2406\u001B[0m formatter \u001B[38;5;241m=\u001B[39m ExcelFormatter(\n\u001B[0;32m 2407\u001B[0m df,\n\u001B[0;32m 2408\u001B[0m na_rep\u001B[38;5;241m=\u001B[39mna_rep,\n\u001B[1;32m (...)\u001B[0m\n\u001B[0;32m 2415\u001B[0m inf_rep\u001B[38;5;241m=\u001B[39minf_rep,\n\u001B[0;32m 2416\u001B[0m )\n\u001B[1;32m-> 2417\u001B[0m formatter\u001B[38;5;241m.\u001B[39mwrite(\n\u001B[0;32m 2418\u001B[0m excel_writer,\n\u001B[0;32m 2419\u001B[0m sheet_name\u001B[38;5;241m=\u001B[39msheet_name,\n\u001B[0;32m 2420\u001B[0m startrow\u001B[38;5;241m=\u001B[39mstartrow,\n\u001B[0;32m 2421\u001B[0m startcol\u001B[38;5;241m=\u001B[39mstartcol,\n\u001B[0;32m 2422\u001B[0m freeze_panes\u001B[38;5;241m=\u001B[39mfreeze_panes,\n\u001B[0;32m 2423\u001B[0m engine\u001B[38;5;241m=\u001B[39mengine,\n\u001B[0;32m 2424\u001B[0m storage_options\u001B[38;5;241m=\u001B[39mstorage_options,\n\u001B[0;32m 2425\u001B[0m engine_kwargs\u001B[38;5;241m=\u001B[39mengine_kwargs,\n\u001B[0;32m 2426\u001B[0m )\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\formats\\excel.py:943\u001B[0m, in \u001B[0;36mExcelFormatter.write\u001B[1;34m(self, writer, sheet_name, startrow, startcol, freeze_panes, engine, storage_options, engine_kwargs)\u001B[0m\n\u001B[0;32m 941\u001B[0m need_save \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m 942\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m--> 943\u001B[0m writer \u001B[38;5;241m=\u001B[39m ExcelWriter(\n\u001B[0;32m 944\u001B[0m writer,\n\u001B[0;32m 945\u001B[0m engine\u001B[38;5;241m=\u001B[39mengine,\n\u001B[0;32m 946\u001B[0m storage_options\u001B[38;5;241m=\u001B[39mstorage_options,\n\u001B[0;32m 947\u001B[0m engine_kwargs\u001B[38;5;241m=\u001B[39mengine_kwargs,\n\u001B[0;32m 948\u001B[0m )\n\u001B[0;32m 949\u001B[0m need_save \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[0;32m 951\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\excel\\_xlsxwriter.py:204\u001B[0m, in \u001B[0;36mXlsxWriter.__init__\u001B[1;34m(self, path, engine, date_format, datetime_format, mode, storage_options, if_sheet_exists, engine_kwargs, **kwargs)\u001B[0m\n\u001B[0;32m 201\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m mode \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124ma\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[0;32m 202\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mAppend mode is not supported with xlsxwriter!\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m--> 204\u001B[0m \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39m\u001B[38;5;21m__init__\u001B[39m(\n\u001B[0;32m 205\u001B[0m path,\n\u001B[0;32m 206\u001B[0m engine\u001B[38;5;241m=\u001B[39mengine,\n\u001B[0;32m 207\u001B[0m date_format\u001B[38;5;241m=\u001B[39mdate_format,\n\u001B[0;32m 208\u001B[0m datetime_format\u001B[38;5;241m=\u001B[39mdatetime_format,\n\u001B[0;32m 209\u001B[0m mode\u001B[38;5;241m=\u001B[39mmode,\n\u001B[0;32m 210\u001B[0m storage_options\u001B[38;5;241m=\u001B[39mstorage_options,\n\u001B[0;32m 211\u001B[0m if_sheet_exists\u001B[38;5;241m=\u001B[39mif_sheet_exists,\n\u001B[0;32m 212\u001B[0m engine_kwargs\u001B[38;5;241m=\u001B[39mengine_kwargs,\n\u001B[0;32m 213\u001B[0m )\n\u001B[0;32m 215\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m 216\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_book \u001B[38;5;241m=\u001B[39m Workbook(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_handles\u001B[38;5;241m.\u001B[39mhandle, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mengine_kwargs)\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\excel\\_base.py:1246\u001B[0m, in \u001B[0;36mExcelWriter.__init__\u001B[1;34m(self, path, engine, date_format, datetime_format, mode, storage_options, if_sheet_exists, engine_kwargs)\u001B[0m\n\u001B[0;32m 1242\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_handles \u001B[38;5;241m=\u001B[39m IOHandles(\n\u001B[0;32m 1243\u001B[0m cast(IO[\u001B[38;5;28mbytes\u001B[39m], path), compression\u001B[38;5;241m=\u001B[39m{\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mcompression\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;28;01mNone\u001B[39;00m}\n\u001B[0;32m 1244\u001B[0m )\n\u001B[0;32m 1245\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(path, ExcelWriter):\n\u001B[1;32m-> 1246\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_handles \u001B[38;5;241m=\u001B[39m get_handle(\n\u001B[0;32m 1247\u001B[0m path, mode, storage_options\u001B[38;5;241m=\u001B[39mstorage_options, is_text\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m 1248\u001B[0m )\n\u001B[0;32m 1249\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_cur_sheet \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m 1251\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m date_format \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
"File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\pandas\\io\\common.py:882\u001B[0m, in \u001B[0;36mget_handle\u001B[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001B[0m\n\u001B[0;32m 873\u001B[0m handle \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mopen\u001B[39m(\n\u001B[0;32m 874\u001B[0m handle,\n\u001B[0;32m 875\u001B[0m ioargs\u001B[38;5;241m.\u001B[39mmode,\n\u001B[1;32m (...)\u001B[0m\n\u001B[0;32m 878\u001B[0m newline\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m 879\u001B[0m )\n\u001B[0;32m 880\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m 881\u001B[0m \u001B[38;5;66;03m# Binary mode\u001B[39;00m\n\u001B[1;32m--> 882\u001B[0m handle \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mopen\u001B[39m(handle, ioargs\u001B[38;5;241m.\u001B[39mmode)\n\u001B[0;32m 883\u001B[0m handles\u001B[38;5;241m.\u001B[39mappend(handle)\n\u001B[0;32m 885\u001B[0m \u001B[38;5;66;03m# Convert BytesIO or file objects passed with an encoding\u001B[39;00m\n",
"\u001B[1;31mPermissionError\u001B[0m: [Errno 13] Permission denied: 'D:\\\\Idea Project\\\\F6+宜搭+其它(1)\\\\new\\\\文件输出\\\\有礼云车辆信息.xlsx'"
]
}
],
"execution_count": 4
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 获取客户列表",
"id": "bffc10bd411fc9f1"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-07T05:25:22.396215Z",
"start_time": "2025-04-07T04:44:51.759632Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"\n",
"url = 'https://www.4008778515.com/Dlmember/getAllMemberlist2'\n",
"\n",
"all_data = []\n",
"request_headers = {\n",
" \"Host\": \"www.4008778515.com\",\n",
" \"Content-Type\": \"application/x-www-form-urlencoded; charset=UTF-8\",\n",
" \"Content-Length\": \"2663\",\n",
" \"Accept\": \"application/json, text/javascript, */*; q=0.01\",\n",
" \"Accept-Encoding\": \"gzip, deflate, br, zstd\",\n",
" \"Accept-Language\": \"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6\",\n",
" \"Cookie\": \"PHPSESSID=7btmjj5l56o3sfqcllv5h3eqs0; Hm_lvt_15244cf00ec0dd2686e4c0e425aecdd5=1743990464; HMACCOUNT=ABFCA62083E00432; Hm_lpvt_15244cf00ec0dd2686e4c0e425aecdd5=1743991737\",\n",
" \"Origin\": \"https://www.4008778515.com\",\n",
" \"Priority\": \"u=1, i\",\n",
" \"Referer\": \"https://www.4008778515.com/index.php/Dlmember/index\",\n",
" \"Sec-Ch-Ua\": '\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Microsoft Edge\";v=\"134\"',\n",
" \"Sec-Ch-Ua-Mobile\": \"?0\",\n",
" \"Sec-Ch-Ua-Platform\": '\"Windows\"',\n",
" \"Sec-Fetch-Dest\": \"empty\",\n",
" \"Sec-Fetch-Mode\": \"cors\",\n",
" \"Sec-Fetch-Site\": \"same-origin\",\n",
" \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0\",\n",
" \"X-Requested-With\": \"XMLHttpRequest\"\n",
"}\n",
"\n",
"# for lim in tqdm(range(0, 3)):\n",
"\n",
"data = {\n",
" \"draw\": 2,\n",
" \"columns[0][data]\": \"Name\",\n",
" \"columns[0][name]\": \"\",\n",
" \"columns[0][searchable]\": True,\n",
" \"columns[0][orderable]\": False,\n",
" \"columns[0][search][value]\": \"\",\n",
" \"columns[0][search][regex]\": False,\n",
" \"columns[1][data]\": \"MemberCard\",\n",
" \"columns[1][name]\": \"\",\n",
" \"columns[1][searchable]\": True,\n",
" \"columns[1][orderable]\": False,\n",
" \"columns[1][search][value]\": \"\",\n",
" \"columns[1][search][regex]\": False,\n",
" \"columns[2][data]\": \"Balance\",\n",
" \"columns[2][name]\": \"\",\n",
" \"columns[2][searchable]\": True,\n",
" \"columns[2][orderable]\": False,\n",
" \"columns[2][search][value]\": \"\",\n",
" \"columns[2][search][regex]\": False,\n",
" \"columns[3][data]\": \"Give\",\n",
" \"columns[3][name]\": \"\",\n",
" \"columns[3][searchable]\": True,\n",
" \"columns[3][orderable]\": False,\n",
" \"columns[3][search][value]\": \"\",\n",
" \"columns[3][search][regex]\": False,\n",
" \"columns[4][data]\": \"Integral\",\n",
" \"columns[4][name]\": \"\",\n",
" \"columns[4][searchable]\": True,\n",
" \"columns[4][orderable]\": False,\n",
" \"columns[4][search][value]\": \"\",\n",
" \"columns[4][search][regex]\": False,\n",
" \"columns[5][data]\": \"Phone\",\n",
" \"columns[5][name]\": \"\",\n",
" \"columns[5][searchable]\": True,\n",
" \"columns[5][orderable]\": False,\n",
" \"columns[5][search][value]\": \"\",\n",
" \"columns[5][search][regex]\": False,\n",
" \"columns[6][data]\": \"GroupingRelationName\",\n",
" \"columns[6][name]\": \"\",\n",
" \"columns[6][searchable]\": True,\n",
" \"columns[6][orderable]\": False,\n",
" \"columns[6][search][value]\": \"\",\n",
" \"columns[6][search][regex]\": False,\n",
" \"columns[7][data]\": \"Rank_obj\",\n",
" \"columns[7][name]\": \"\",\n",
" \"columns[7][searchable]\": True,\n",
" \"columns[7][orderable]\": False,\n",
" \"columns[7][search][value]\": \"\",\n",
" \"columns[7][search][regex]\": False,\n",
" \"columns[8][data]\": \"ChainShopName\",\n",
" \"columns[8][name]\": \"\",\n",
" \"columns[8][searchable]\": True,\n",
" \"columns[8][orderable]\": False,\n",
" \"columns[8][search][value]\": \"\",\n",
" \"columns[8][search][regex]\": False,\n",
" \"columns[9][data]\": \"Createtime\",\n",
" \"columns[9][name]\": \"\",\n",
" \"columns[9][searchable]\": True,\n",
" \"columns[9][orderable]\": False,\n",
" \"columns[9][search][value]\": \"\",\n",
" \"columns[9][search][regex]\": False,\n",
" \"columns[10][data]\": \"ID\",\n",
" \"columns[10][name]\": \"\",\n",
" \"columns[10][searchable]\": True,\n",
" \"columns[10][orderable]\": False,\n",
" \"columns[10][search][value]\": \"\",\n",
" \"columns[10][search][regex]\": False,\n",
" \"order[0][column]\": 0,\n",
" \"order[0][dir]\": \"desc\",\n",
" \"start\": 0,\n",
" \"length\": 5000,\n",
" \"search[value]\": \"\",\n",
" \"search[regex]\": False,\n",
" \"DlmTerm\": 1,\n",
" \"IsCheckChainShop\": 0,\n",
" \"Status\": 1,\n",
" \"RankID\": -1,\n",
" \"GroupingID\": 0,\n",
" \"searchContent\": \"\",\n",
" \"wxSendType\": \"\",\n",
" \"Balance_Sort_Type\": \"\",\n",
" \"caller\": \"\",\n",
" \"search_mid\": 0,\n",
" \"linkid\": \"52aa9b1bb7a9045eb0e272b57f696375\"\n",
"}\n",
"print(data)\n",
"\n",
"res = requests.post(url, headers=request_headers, data=data)\n",
"print(res.json())\n",
"data_list = res.json().get('data')\n",
"if data_list:\n",
" for data in tqdm(data_list):\n",
" retries = 5 # 最大重试次数\n",
" success = False # 标记是否成功\n",
"\n",
" while retries > 0 and not success:\n",
" try:\n",
" # 提取 ID 并构造请求数据\n",
" id = data.get('ID')\n",
" url = f'https://www.4008778515.com/Dlmember/getDetailData'\n",
" single_level_dict = {\n",
" \"u_id\": id,\n",
" \"NoDlmTerm\": \"1\",\n",
" \"linkid\": \"4acb20caa66b767e9700cd263d2698ea\"\n",
" }\n",
"\n",
" # 发送 POST 请求\n",
" res = requests.post(url, headers=request_headers, data=single_level_dict)\n",
" res.raise_for_status() # 检查请求是否成功(抛出 HTTP 错误)\n",
"\n",
" # 解析返回的 JSON 数据并更新原始数据\n",
" data1 = res.json().get('data')\n",
" data.update(data1)\n",
"\n",
" # 添加到 all_data 列表\n",
" all_data.append(data)\n",
"\n",
" # 标记为成功\n",
" success = True\n",
"\n",
" except Exception as e:\n",
" # 捕获任何异常并打印错误信息\n",
" print(f\"Error occurred: {e}. Retrying ({retries} attempts left)...\")\n",
" retries -= 1 # 减少重试次数\n",
" time.sleep(1) # 等待 1 秒后再重试\n",
"\n",
" if not success:\n",
" print(f\"Failed to process data with ID {id} after 5 attempts.\")\n",
"\n",
" # 每次处理完一条数据后等待 0.5 秒\n",
" time.sleep(0.5)\n",
"\n",
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云客户信息.xlsx', index=False)"
],
"id": "2ee2bb3bf7d3c0f",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'draw': 2, 'columns[0][data]': 'Name', 'columns[0][name]': '', 'columns[0][searchable]': True, 'columns[0][orderable]': False, 'columns[0][search][value]': '', 'columns[0][search][regex]': False, 'columns[1][data]': 'MemberCard', 'columns[1][name]': '', 'columns[1][searchable]': True, 'columns[1][orderable]': False, 'columns[1][search][value]': '', 'columns[1][search][regex]': False, 'columns[2][data]': 'Balance', 'columns[2][name]': '', 'columns[2][searchable]': True, 'columns[2][orderable]': False, 'columns[2][search][value]': '', 'columns[2][search][regex]': False, 'columns[3][data]': 'Give', 'columns[3][name]': '', 'columns[3][searchable]': True, 'columns[3][orderable]': False, 'columns[3][search][value]': '', 'columns[3][search][regex]': False, 'columns[4][data]': 'Integral', 'columns[4][name]': '', 'columns[4][searchable]': True, 'columns[4][orderable]': False, 'columns[4][search][value]': '', 'columns[4][search][regex]': False, 'columns[5][data]': 'Phone', 'columns[5][name]': '', 'columns[5][searchable]': True, 'columns[5][orderable]': False, 'columns[5][search][value]': '', 'columns[5][search][regex]': False, 'columns[6][data]': 'GroupingRelationName', 'columns[6][name]': '', 'columns[6][searchable]': True, 'columns[6][orderable]': False, 'columns[6][search][value]': '', 'columns[6][search][regex]': False, 'columns[7][data]': 'Rank_obj', 'columns[7][name]': '', 'columns[7][searchable]': True, 'columns[7][orderable]': False, 'columns[7][search][value]': '', 'columns[7][search][regex]': False, 'columns[8][data]': 'ChainShopName', 'columns[8][name]': '', 'columns[8][searchable]': True, 'columns[8][orderable]': False, 'columns[8][search][value]': '', 'columns[8][search][regex]': False, 'columns[9][data]': 'Createtime', 'columns[9][name]': '', 'columns[9][searchable]': True, 'columns[9][orderable]': False, 'columns[9][search][value]': '', 'columns[9][search][regex]': False, 'columns[10][data]': 'ID', 'columns[10][name]': '', 'columns[10][searchable]': True, 'columns[10][orderable]': False, 'columns[10][search][value]': '', 'columns[10][search][regex]': False, 'order[0][column]': 0, 'order[0][dir]': 'desc', 'start': 0, 'length': 5000, 'search[value]': '', 'search[regex]': False, 'DlmTerm': 1, 'IsCheckChainShop': 0, 'Status': 1, 'RankID': -1, 'GroupingID': 0, 'searchContent': '', 'wxSendType': '', 'Balance_Sort_Type': '', 'caller': '', 'search_mid': 0, 'linkid': '52aa9b1bb7a9045eb0e272b57f696375'}\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"IOPub data rate exceeded.\n",
"The Jupyter server will temporarily stop sending output\n",
"to the client in order to avoid crashing it.\n",
"To change this limit, set the config variable\n",
"`--ServerApp.iopub_data_rate_limit`.\n",
"\n",
"Current values:\n",
"ServerApp.iopub_data_rate_limit=1000000.0 (bytes/sec)\n",
"ServerApp.rate_limit_window=3.0 (secs)\n",
"\n",
"100%|██████████| 3529/3529 [40:24<00:00, 1.46it/s]\n"
]
}
],
"execution_count": 3
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-07T03:32:09.166322Z",
"start_time": "2025-04-07T03:32:08.395297Z"
}
},
"cell_type": "code",
"source": [
"df1 = pd.DataFrame(all_data)\n",
"df1.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云客户信息.xlsx', index=False)"
],
"id": "59f4cdbbd9848a23",
"outputs": [],
"execution_count": 48
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 历史维修记录",
"id": "5411e22aa78fb593"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-11T05:28:57.191050Z",
"start_time": "2025-04-11T04:05:03.202273Z"
}
},
"cell_type": "code",
"source": [
"import requests\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"import time\n",
"\n",
"url = 'https://www.4008778515.com/Report/carservicesbillsrecord_data'\n",
"all_data = []\n",
"all_data_list = []\n",
"headers = {\n",
" 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\n",
" 'Cookie': 'PHPSESSID=7btmjj5l56o3sfqcllv5h3eqs0; Hm_lvt_15244cf00ec0dd2686e4c0e425aecdd5=1743990464; HMACCOUNT=ABFCA62083E00432; shopsernum=109136; username=13484722095; password=71ab90749125dcd2534d5bc1f9de390f; Hm_lpvt_15244cf00ec0dd2686e4c0e425aecdd5=1744337012',\n",
" 'Origin': 'https://www.4008778515.com',\n",
" 'Referer': 'https://www.4008778515.com/Carservicesbills/indexv2?bill_id=2557165',\n",
" 'Sec-Ch-Ua': '\"Microsoft Edge\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\"',\n",
" 'Sec-Ch-Ua-Mobile': '?0',\n",
" 'Sec-Ch-Ua-Platform': '\"Windows\"',\n",
" 'Sec-Fetch-Dest': 'empty',\n",
" 'Sec-Fetch-Mode': 'cors',\n",
" 'Sec-Fetch-Site': 'same-origin',\n",
" 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',\n",
" 'X-Requested-With': 'XMLHttpRequest'\n",
"}\n",
"for j in tqdm(range(0, 342)):\n",
" params = {\n",
" \"draw\": \"5\",\n",
" \"columns[0][data]\": \"BillCode\",\n",
" \"columns[0][name]\": \"\",\n",
" \"columns[0][searchable]\": \"true\",\n",
" \"columns[0][orderable]\": \"false\",\n",
" \"columns[0][search][value]\": \"\",\n",
" \"columns[0][search][regex]\": \"false\",\n",
" \"columns[1][data]\": \"BillDate\",\n",
" \"columns[1][name]\": \"\",\n",
" \"columns[1][searchable]\": \"true\",\n",
" \"columns[1][orderable]\": \"false\",\n",
" \"columns[1][search][value]\": \"\",\n",
" \"columns[1][search][regex]\": \"false\",\n",
" \"columns[2][data]\": \"MoneyOpeTime\",\n",
" \"columns[2][name]\": \"\",\n",
" \"columns[2][searchable]\": \"true\",\n",
" \"columns[2][orderable]\": \"false\",\n",
" \"columns[2][search][value]\": \"\",\n",
" \"columns[2][search][regex]\": \"false\",\n",
" \"columns[3][data]\": \"CustomerType\",\n",
" \"columns[3][name]\": \"\",\n",
" \"columns[3][searchable]\": \"true\",\n",
" \"columns[3][orderable]\": \"false\",\n",
" \"columns[3][search][value]\": \"\",\n",
" \"columns[3][search][regex]\": \"false\",\n",
" \"columns[4][data]\": \"CarLicencePlates\",\n",
" \"columns[4][name]\": \"\",\n",
" \"columns[4][searchable]\": \"true\",\n",
" \"columns[4][orderable]\": \"false\",\n",
" \"columns[4][search][value]\": \"\",\n",
" \"columns[4][search][regex]\": \"false\",\n",
" \"columns[5][data]\": \"MemberCard\",\n",
" \"columns[5][name]\": \"\",\n",
" \"columns[5][searchable]\": \"true\",\n",
" \"columns[5][orderable]\": \"false\",\n",
" \"columns[5][search][value]\": \"\",\n",
" \"columns[5][search][regex]\": \"false\",\n",
" \"columns[6][data]\": \"MemberName\",\n",
" \"columns[6][name]\": \"\",\n",
" \"columns[6][searchable]\": \"true\",\n",
" \"columns[6][orderable]\": \"false\",\n",
" \"columns[6][search][value]\": \"\",\n",
" \"columns[6][search][regex]\": \"false\",\n",
" \"columns[7][data]\": \"Receivable\",\n",
" \"columns[7][name]\": \"\",\n",
" \"columns[7][searchable]\": \"true\",\n",
" \"columns[7][orderable]\": \"false\",\n",
" \"columns[7][search][value]\": \"\",\n",
" \"columns[7][search][regex]\": \"false\",\n",
" \"columns[8][data]\": \"PaidDetail\",\n",
" \"columns[8][name]\": \"\",\n",
" \"columns[8][searchable]\": \"true\",\n",
" \"columns[8][orderable]\": \"false\",\n",
" \"columns[8][search][value]\": \"\",\n",
" \"columns[8][search][regex]\": \"false\",\n",
" \"columns[9][data]\": \"Status\",\n",
" \"columns[9][name]\": \"\",\n",
" \"columns[9][searchable]\": \"true\",\n",
" \"columns[9][orderable]\": \"false\",\n",
" \"columns[9][search][value]\": \"\",\n",
" \"columns[9][search][regex]\": \"false\",\n",
" \"columns[10][data]\": \"Actually\",\n",
" \"columns[10][name]\": \"\",\n",
" \"columns[10][searchable]\": \"true\",\n",
" \"columns[10][orderable]\": \"false\",\n",
" \"columns[10][search][value]\": \"\",\n",
" \"columns[10][search][regex]\": \"false\",\n",
" \"columns[11][data]\": \"Creator\",\n",
" \"columns[11][name]\": \"\",\n",
" \"columns[11][searchable]\": \"true\",\n",
" \"columns[11][orderable]\": \"false\",\n",
" \"columns[11][search][value]\": \"\",\n",
" \"columns[11][search][regex]\": \"false\",\n",
" \"columns[12][data]\": \"RepairType\",\n",
" \"columns[12][name]\": \"\",\n",
" \"columns[12][searchable]\": \"true\",\n",
" \"columns[12][orderable]\": \"false\",\n",
" \"columns[12][search][value]\": \"\",\n",
" \"columns[12][search][regex]\": \"false\",\n",
" \"order[0][column]\": \"0\",\n",
" \"order[0][dir]\": \"asc\",\n",
" \"start\": f\"{j * 100}\",\n",
" \"length\": \"100\",\n",
" \"search[value]\": \"\",\n",
" \"search[regex]\": \"false\",\n",
" \"StartDate\": \"2018-04-01\",\n",
" \"EndDate\": \"2025-04-07\",\n",
" \"Status\": \"1\",\n",
" \"BillPayType\": \"-1\",\n",
" \"CarLicencePlates\": \"\",\n",
" \"Creator\": \"-1\",\n",
" \"RepairType\": \"\",\n",
" \"CustomerType\": \"0\",\n",
" \"DateType\": \"MoneyOpeTime\",\n",
" \"NatureOfBill\": \"\"\n",
" }\n",
"\n",
" res = requests.post(url, headers=headers, data=params)\n",
" data_list = res.json().get(\"data\")\n",
" all_data_list.extend(data_list)\n",
"\n",
"dfn = pd.DataFrame(all_data_list)\n",
"dfn.to_csv(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录1.csv', index=False)\n",
"# print(data)\n",
"for data in tqdm(all_data_list):\n",
" id = data.get(\"ID\")\n",
" billcode = data.get(\"BillCode\")\n",
"\n",
" url = 'https://www.4008778515.com/Carservicesbills/getBillDataDetail'\n",
" params = {\n",
" \"BillID\": id,\n",
" \"BillCode\": billcode\n",
" }\n",
"\n",
" attempts = 0\n",
" while attempts < 15:\n",
" try:\n",
" res = requests.post(url, headers=headers, data=params)\n",
" res.raise_for_status() # 确保请求成功,失败时抛出异常\n",
" data2 = res.json()\n",
" data.update(data2)\n",
" all_data.append(data)\n",
" break # 如果成功,则跳出循环\n",
" except Exception as e:\n",
" print(f\"尝试 {attempts + 1} 失败: {e}\")\n",
" attempts += 1\n",
" if attempts == 15:\n",
" print(\"达到最大重试次数,跳过此条记录。\")\n",
" else:\n",
" time.sleep(2) # 等待2秒后重试\n",
"\n",
" time.sleep(0.5) # 每次请求之间的等待时间\n",
"\n",
" # print(data)\n",
" # break\n",
"df2 = pd.DataFrame(all_data)\n",
"df2.to_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录.xlsx', index=False)"
],
"id": "520b3f64d351a3ea",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 342/342 [04:08<00:00, 1.38it/s]\n",
" 1%| | 258/34108 [03:02<6:36:28, 1.42it/s]"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"尝试 1 失败: HTTPSConnectionPool(host='www.4008778515.com', port=443): Max retries exceeded with url: /Carservicesbills/getBillDataDetail (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x0000029D9FF8A240>, 'Connection to www.4008778515.com timed out. (connect timeout=None)'))\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" 20%|█▉ | 6751/34108 [1:19:44<5:23:07, 1.41it/s]\n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[1;31mKeyboardInterrupt\u001B[0m Traceback (most recent call last)",
"Cell \u001B[1;32mIn[22], line 156\u001B[0m\n\u001B[0;32m 153\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m 154\u001B[0m time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;241m2\u001B[39m) \u001B[38;5;66;03m# 等待2秒后重试\u001B[39;00m\n\u001B[1;32m--> 156\u001B[0m time\u001B[38;5;241m.\u001B[39msleep(\u001B[38;5;241m0.5\u001B[39m) \u001B[38;5;66;03m# 每次请求之间的等待时间\u001B[39;00m\n\u001B[0;32m 158\u001B[0m \u001B[38;5;66;03m# print(data)\u001B[39;00m\n\u001B[0;32m 159\u001B[0m \u001B[38;5;66;03m# break\u001B[39;00m\n\u001B[0;32m 160\u001B[0m df2 \u001B[38;5;241m=\u001B[39m pd\u001B[38;5;241m.\u001B[39mDataFrame(all_data)\n",
"\u001B[1;31mKeyboardInterrupt\u001B[0m: "
]
}
],
"execution_count": 22
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 历史维修记录处理",
"id": "6d6dbd3f1209bc80"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-11T09:26:24.794588Z",
"start_time": "2025-04-11T09:19:44.508134Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"from tqdm import tqdm\n",
"import phpserialize\n",
"import ast\n",
"import os\n",
"\n",
"# 读取 Excel 文件\n",
"df = pd.read_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录.xlsx')\n",
"\n",
"# 打印列名以确认\n",
"print(\"Columns:\", df.columns)\n",
"\n",
"\n",
"# 定义解析和展开函数\n",
"def expand_otherslist(row):\n",
" try:\n",
" otherslist_str = row['OthersList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(otherslist_str) or not isinstance(otherslist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" otherslist_data = phpserialize.loads(otherslist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing OthersList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in otherslist_data.values():\n",
" new_row = row.to_dict()\n",
" new_row.pop('OthersList', None)\n",
" new_row.update(item)\n",
" expanded_rows.append(new_row)\n",
"\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_carmaintainget(row):\n",
" try:\n",
" carmaintainget_str = row['Carmaintainget']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(carmaintainget_str) or not isinstance(carmaintainget_str, str):\n",
" return []\n",
"\n",
" # 如果 Carmaintainget 是字符串形式的列表,尝试用 ast.literal_eval 转换为 Python 列表\n",
" carmaintainget_list = ast.literal_eval(carmaintainget_str)\n",
" except (ValueError, SyntaxError):\n",
" carmaintainget_list = [] # 如果解析失败,返回空列表\n",
"\n",
" expanded_rows = []\n",
" for item in carmaintainget_list:\n",
" new_row = row.to_dict()\n",
" new_row.pop('Carmaintainget', None)\n",
" new_row.update(item) # 将列表中的每个字典合并到新行\n",
" expanded_rows.append(new_row)\n",
"\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_partlist(row):\n",
" try:\n",
" partlist_str = row['PartsList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(partlist_str) or not isinstance(partlist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" partlist_data = phpserialize.loads(partlist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing PartsList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in partlist_data.values():\n",
" new_row = row.to_dict()\n",
" new_row.pop('PartsList', None)\n",
" new_row.update(item)\n",
" expanded_rows.append(new_row)\n",
"\n",
" return expanded_rows\n",
"\n",
"\n",
"# 展开数据\n",
"expanded_otherslist = []\n",
"expanded_carmaintainget = []\n",
"expanded_partlist = []\n",
"expanded_other_info = []\n",
"\n",
"# 使用 tqdm 显示进度条,设置 miniters 和 smoothing 参数\n",
"for _, row in tqdm(df.iterrows(), total=len(df), desc=\"Processing rows\", miniters=100, smoothing=0.1):\n",
" # 展开 otherslist\n",
" otherslist_rows = expand_otherslist(row)\n",
" expanded_otherslist.extend(otherslist_rows)\n",
"\n",
" # 展开 Carmaintainget\n",
" carmaintainget_rows = expand_carmaintainget(row)\n",
" expanded_carmaintainget.extend(carmaintainget_rows)\n",
"\n",
" # 展开 Partlist\n",
" partlist_rows = expand_partlist(row)\n",
" expanded_partlist.extend(partlist_rows)\n",
"\n",
" # 获取最大行数\n",
" max_rows = max(\n",
" len(otherslist_rows) if otherslist_rows else 0,\n",
" len(carmaintainget_rows) if carmaintainget_rows else 0,\n",
" len(partlist_rows) if partlist_rows else 0\n",
" )\n",
"\n",
" # 如果三者都为空,则跳过该行\n",
" if max_rows == 0:\n",
" continue\n",
"\n",
" # 生成其他信息组\n",
" other_info_row = row.to_dict() # 将 Series 转换为字典\n",
" other_info_row.pop('OthersList', None) # 删除指定键(注意大小写)\n",
" other_info_row.pop('Carmaintainget', None)\n",
" other_info_row.pop('PartsList', None)\n",
" other_info_rows = [other_info_row] * max_rows # 复制其他信息组\n",
" expanded_other_info.extend(other_info_rows)\n",
"\n",
"# 创建新的 DataFrame\n",
"df_otherslist = pd.DataFrame(expanded_otherslist).add_prefix('otherslist_')\n",
"df_carmaintainget = pd.DataFrame(expanded_carmaintainget).add_prefix('carmaintainget_')\n",
"df_partlist = pd.DataFrame(expanded_partlist).add_prefix('Partslist_')\n",
"df_other_info = pd.DataFrame(expanded_other_info)\n",
"\n",
"import json\n",
"\n",
"# 合并所有数据\n",
"final_df = pd.concat([df_other_info, df_otherslist, df_carmaintainget, df_partlist], axis=1)\n",
"\n",
"# 检查并移除内容重复的列\n",
"columns_to_keep = []\n",
"seen_columns_content = {}\n",
"\n",
"# 使用 tqdm 显示进度条\n",
"for col in tqdm(final_df.columns, desc=\"Checking columns for duplicates\", unit=\"column\"):\n",
" # 将列内容转换为可哈希的形式\n",
" try:\n",
" # 如果列内容是字典或列表,先转换为 JSON 字符串\n",
" col_content = tuple(\n",
" final_df[col].apply(\n",
" lambda x: json.dumps(x, sort_keys=True) if isinstance(x, (dict, list)) else x\n",
" ).values\n",
" )\n",
" except Exception as e:\n",
" print(f\"Error processing column {col}: {e}\")\n",
" continue\n",
"\n",
" if col_content not in seen_columns_content:\n",
" columns_to_keep.append(col)\n",
" seen_columns_content[col_content] = col # 记录第一次出现的列名\n",
" else:\n",
" print(f\"Duplicate content column removed: {col} (kept: {seen_columns_content[col_content]})\")\n",
"\n",
"# 保留唯一的列\n",
"final_df = final_df[columns_to_keep]\n",
"\n",
"# 确保输出目录存在\n",
"output_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录——数据处理.xlsx'\n",
"os.makedirs(os.path.dirname(output_path), exist_ok=True)\n",
"\n",
"# 输出到 Excel 文件\n",
"final_df.to_excel(output_path, index=False)"
],
"id": "236a53a95a662e9b",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Columns: Index(['ID', 'ShopID', 'FromShopID', 'CustomerType', 'Codes', 'BillCode',\n",
" 'BillDate', 'MasterMID', 'MemberID', 'MemberName', 'MemberPhone',\n",
" 'MemberDescription', 'CarID', 'CarLicencePlates', 'CarBrand',\n",
" 'CarSeries', 'CarBrandModel', 'CarColor', 'DriverName', 'DriverPhone',\n",
" 'TroubleDescriptions', 'RepairSuggestion', 'RepairType',\n",
" 'ServiceExpense', 'PartsExoense', 'PartsList', 'TaxRate', 'TaxMoney',\n",
" 'Receivable', 'Actually', 'PaidDetail', 'VouchersList', 'FreePay',\n",
" 'GivePay', 'Status', 'Description', 'Closed', 'Creator', 'Createtime',\n",
" 'Updator', 'Updatetime', 'Closedator', 'Closedatetime', 'BillBasic',\n",
" 'OthersList', 'CarAppearance', 'IsCreatedBy', 'IsChecked',\n",
" 'Customerservice', 'ifclose', 'DirectOps', 'PaiedMoneyOpeTime',\n",
" 'RebuildID', 'MoneyOpeTime', 'MoneyOper', 'IsLft', 'LftPayTime',\n",
" 'NatureOfBill', 'InsuranceCompany', 'FixedLossAmount',\n",
" 'InsuranceChargingWay', 'InsuranceStaff', 'OpeDesc', 'ServiceCost_All',\n",
" 'CommodityCost_All', 'ifStockOutFinished', 'Region',\n",
" 'is_arrears_Settle', 'Old_MemberID', 'is_bill_free', 'mall_orderid',\n",
" 'mall_ordernum', 'JianKangDangAn_uptime', 'JianKangDangAn_Index',\n",
" 'Consultant_name', 'Consultant_id', 'Balance', 'MemberName2',\n",
" 'MemberCard', 'MemberCardLevel', 'RegistrationNum', 'CarBrandModel_',\n",
" 'PaidDetail_value', 'Status_value', 'thisMonth', 'thisTimes', 'sta',\n",
" 'data', 'ResultData', 'voucherBalance', 'Carmaintainget', 'msg',\n",
" 'mem_voucherBalance', '0', 'act_res', 'Preferential_All',\n",
" 'ActuallyPaidType'],\n",
" dtype='object')\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Processing rows: 100%|██████████| 40860/40860 [00:18<00:00, 2182.20it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Duplicate content column removed: MasterMID (kept: FromShopID)\n",
"Duplicate content column removed: TaxRate (kept: FromShopID)\n",
"Duplicate content column removed: TaxMoney (kept: FromShopID)\n",
"Duplicate content column removed: Closed (kept: FromShopID)\n",
"Duplicate content column removed: IsChecked (kept: FromShopID)\n",
"Duplicate content column removed: IsLft (kept: FromShopID)\n",
"Duplicate content column removed: Old_MemberID (kept: FromShopID)\n",
"Duplicate content column removed: is_bill_free (kept: FromShopID)\n",
"Duplicate content column removed: mall_orderid (kept: FromShopID)\n",
"Duplicate content column removed: JianKangDangAn_uptime (kept: FromShopID)\n",
"Duplicate content column removed: Consultant_id (kept: FromShopID)\n",
"Duplicate content column removed: sta (kept: Status_value)\n",
"Duplicate content column removed: otherslist_ConstructionStaffobj (kept: otherslist_SaleStaffobj)\n"
]
}
],
"execution_count": 37
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-11T09:51:09.006807Z",
"start_time": "2025-04-11T09:47:50.289433Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"from tqdm import tqdm\n",
"import phpserialize\n",
"import ast\n",
"import os\n",
"\n",
"# 读取 Excel 文件\n",
"df = pd.read_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录.xlsx')\n",
"\n",
"# 打印列名以确认\n",
"print(\"Columns:\", df.columns)\n",
"\n",
"# 定义解析和展开函数\n",
"def expand_otherslist(row):\n",
" try:\n",
" otherslist_str = row['OthersList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(otherslist_str) or not isinstance(otherslist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" otherslist_data = phpserialize.loads(otherslist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing OthersList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in otherslist_data.values():\n",
" expanded_rows.append(item) # 只保留 OthersList 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_carmaintainget(row):\n",
" try:\n",
" carmaintainget_str = row['Carmaintainget']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(carmaintainget_str) or not isinstance(carmaintainget_str, str):\n",
" return []\n",
"\n",
" # 如果 Carmaintainget 是字符串形式的列表,尝试用 ast.literal_eval 转换为 Python 列表\n",
" carmaintainget_list = ast.literal_eval(carmaintainget_str)\n",
" except (ValueError, SyntaxError):\n",
" carmaintainget_list = [] # 如果解析失败,返回空列表\n",
"\n",
" expanded_rows = []\n",
" for item in carmaintainget_list:\n",
" expanded_rows.append(item) # 只保留 Carmaintainget 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_partlist(row):\n",
" try:\n",
" partlist_str = row['PartsList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(partlist_str) or not isinstance(partlist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" partlist_data = phpserialize.loads(partlist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing PartsList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in partlist_data.values():\n",
" expanded_rows.append(item) # 只保留 PartsList 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"# 展开数据\n",
"expanded_otherslist = []\n",
"expanded_carmaintainget = []\n",
"expanded_partlist = []\n",
"expanded_other_info = []\n",
"\n",
"# 使用 tqdm 显示进度条,设置 miniters 和 smoothing 参数\n",
"for _, row in tqdm(df.iterrows(), total=len(df), desc=\"Processing rows\", miniters=100, smoothing=0.1):\n",
" # 获取最大行数\n",
" max_rows = max(\n",
" len(expand_otherslist(row)) if expand_otherslist(row) else 0,\n",
" len(expand_carmaintainget(row)) if expand_carmaintainget(row) else 0,\n",
" len(expand_partlist(row)) if expand_partlist(row) else 0\n",
" )\n",
"\n",
" # 如果三者都为空,则跳过该行\n",
" if max_rows == 0:\n",
" continue\n",
"\n",
" # 添加展开数据\n",
" expanded_otherslist.extend(expand_otherslist(row))\n",
" expanded_carmaintainget.extend(expand_carmaintainget(row))\n",
" expanded_partlist.extend(expand_partlist(row))\n",
"\n",
" # 添加其他信息组\n",
" other_info_row = row.to_dict() # 将 Series 转换为字典\n",
" other_info_row.pop('OthersList', None) # 删除指定键(注意大小写)\n",
" other_info_row.pop('Carmaintainget', None)\n",
" other_info_row.pop('PartsList', None)\n",
" expanded_other_info.extend([other_info_row] * max_rows) # 复制其他信息组\n",
"\n",
"# 创建新的 DataFrame\n",
"df_otherslist = pd.DataFrame(expanded_otherslist).add_prefix('otherslist_')\n",
"df_carmaintainget = pd.DataFrame(expanded_carmaintainget).add_prefix('carmaintainget_')\n",
"df_partlist = pd.DataFrame(expanded_partlist).add_prefix('Partslist_')\n",
"df_other_info = pd.DataFrame(expanded_other_info)\n",
"\n",
"# 合并所有数据\n",
"final_df = pd.concat([df_other_info, df_otherslist, df_carmaintainget, df_partlist], axis=1)\n",
"\n",
"\n",
"# 确保输出目录存在\n",
"output_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录——数据处理1.xlsx'\n",
"os.makedirs(os.path.dirname(output_path), exist_ok=True)\n",
"\n",
"# 输出到 Excel 文件\n",
"final_df.to_excel(output_path, index=False)"
],
"id": "8f43ce0d40beace8",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Columns: Index(['ID', 'ShopID', 'FromShopID', 'CustomerType', 'Codes', 'BillCode',\n",
" 'BillDate', 'MasterMID', 'MemberID', 'MemberName', 'MemberPhone',\n",
" 'MemberDescription', 'CarID', 'CarLicencePlates', 'CarBrand',\n",
" 'CarSeries', 'CarBrandModel', 'CarColor', 'DriverName', 'DriverPhone',\n",
" 'TroubleDescriptions', 'RepairSuggestion', 'RepairType',\n",
" 'ServiceExpense', 'PartsExoense', 'PartsList', 'TaxRate', 'TaxMoney',\n",
" 'Receivable', 'Actually', 'PaidDetail', 'VouchersList', 'FreePay',\n",
" 'GivePay', 'Status', 'Description', 'Closed', 'Creator', 'Createtime',\n",
" 'Updator', 'Updatetime', 'Closedator', 'Closedatetime', 'BillBasic',\n",
" 'OthersList', 'CarAppearance', 'IsCreatedBy', 'IsChecked',\n",
" 'Customerservice', 'ifclose', 'DirectOps', 'PaiedMoneyOpeTime',\n",
" 'RebuildID', 'MoneyOpeTime', 'MoneyOper', 'IsLft', 'LftPayTime',\n",
" 'NatureOfBill', 'InsuranceCompany', 'FixedLossAmount',\n",
" 'InsuranceChargingWay', 'InsuranceStaff', 'OpeDesc', 'ServiceCost_All',\n",
" 'CommodityCost_All', 'ifStockOutFinished', 'Region',\n",
" 'is_arrears_Settle', 'Old_MemberID', 'is_bill_free', 'mall_orderid',\n",
" 'mall_ordernum', 'JianKangDangAn_uptime', 'JianKangDangAn_Index',\n",
" 'Consultant_name', 'Consultant_id', 'Balance', 'MemberName2',\n",
" 'MemberCard', 'MemberCardLevel', 'RegistrationNum', 'CarBrandModel_',\n",
" 'PaidDetail_value', 'Status_value', 'thisMonth', 'thisTimes', 'sta',\n",
" 'data', 'ResultData', 'voucherBalance', 'Carmaintainget', 'msg',\n",
" 'mem_voucherBalance', '0', 'act_res', 'Preferential_All',\n",
" 'ActuallyPaidType'],\n",
" dtype='object')\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Processing rows: 100%|██████████| 40860/40860 [00:27<00:00, 1509.15it/s]\n"
]
}
],
"execution_count": 38
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-11T09:56:05.852246Z",
"start_time": "2025-04-11T09:52:47.929921Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"from tqdm import tqdm\n",
"import phpserialize\n",
"import ast\n",
"import os\n",
"\n",
"# 读取 Excel 文件\n",
"df = pd.read_excel(r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录.xlsx')\n",
"\n",
"# 打印列名以确认\n",
"print(\"Columns:\", df.columns)\n",
"\n",
"# 定义解析和展开函数\n",
"def expand_otherslist(row):\n",
" try:\n",
" otherslist_str = row['OthersList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(otherslist_str) or not isinstance(otherslist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" otherslist_data = phpserialize.loads(otherslist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing OthersList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in otherslist_data.values():\n",
" expanded_rows.append(item) # 只保留 OthersList 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_carmaintainget(row):\n",
" try:\n",
" carmaintainget_str = row['Carmaintainget']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(carmaintainget_str) or not isinstance(carmaintainget_str, str):\n",
" return []\n",
"\n",
" # 如果 Carmaintainget 是字符串形式的列表,尝试用 ast.literal_eval 转换为 Python 列表\n",
" carmaintainget_list = ast.literal_eval(carmaintainget_str)\n",
" except (ValueError, SyntaxError):\n",
" carmaintainget_list = [] # 如果解析失败,返回空列表\n",
"\n",
" expanded_rows = []\n",
" for item in carmaintainget_list:\n",
" expanded_rows.append(item) # 只保留 Carmaintainget 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"def expand_partlist(row):\n",
" try:\n",
" partlist_str = row['PartsList']\n",
"\n",
" # 检查是否为空或 NaN\n",
" if pd.isna(partlist_str) or not isinstance(partlist_str, str):\n",
" return []\n",
"\n",
" # 尝试解析 PHP 序列化字符串\n",
" partlist_data = phpserialize.loads(partlist_str.encode('utf-8'), decode_strings=True)\n",
" except Exception as e:\n",
" print(f\"Error parsing PartsList: {e}\")\n",
" return []\n",
"\n",
" expanded_rows = []\n",
" for item in partlist_data.values():\n",
" expanded_rows.append(item) # 只保留 PartsList 的内容,不复制其他行信息\n",
" return expanded_rows\n",
"\n",
"\n",
"# 使用字典存储每个展开列的数据\n",
"expanded_data = {\n",
" 'otherslist': [],\n",
" 'carmaintainget': [],\n",
" 'partslist': [],\n",
" 'other_info': []\n",
"}\n",
"\n",
"# 使用 tqdm 显示进度条,设置 miniters 和 smoothing 参数\n",
"for _, row in tqdm(df.iterrows(), total=len(df), desc=\"Processing rows\", miniters=100, smoothing=0.1):\n",
" otherslist_rows = expand_otherslist(row)\n",
" carmaintainget_rows = expand_carmaintainget(row)\n",
" partslist_rows = expand_partlist(row)\n",
"\n",
" # 获取每列的实际展开行数\n",
" max_rows = max(\n",
" len(otherslist_rows),\n",
" len(carmaintainget_rows),\n",
" len(partslist_rows)\n",
" )\n",
"\n",
" # 如果三者都为空,则跳过该行\n",
" if max_rows == 0:\n",
" continue\n",
"\n",
" # 添加展开数据\n",
" expanded_data['otherslist'].extend(otherslist_rows)\n",
" expanded_data['carmaintainget'].extend(carmaintainget_rows)\n",
" expanded_data['partslist'].extend(partslist_rows)\n",
"\n",
" # 添加其他信息组\n",
" other_info_row = row.to_dict()\n",
" other_info_row.pop('OthersList', None)\n",
" other_info_row.pop('Carmaintainget', None)\n",
" other_info_row.pop('PartsList', None)\n",
" expanded_data['other_info'].extend([other_info_row] * max_rows)\n",
"\n",
"# 创建新的 DataFrame\n",
"df_otherslist = pd.DataFrame(expanded_data['otherslist']).add_prefix('otherslist_')\n",
"df_carmaintainget = pd.DataFrame(expanded_data['carmaintainget']).add_prefix('carmaintainget_')\n",
"df_partlist = pd.DataFrame(expanded_data['partslist']).add_prefix('Partslist_')\n",
"df_other_info = pd.DataFrame(expanded_data['other_info'])\n",
"\n",
"# 合并所有数据\n",
"final_df = pd.concat([df_other_info, df_otherslist, df_carmaintainget, df_partlist], axis=1)\n",
"\n",
"# 确保输出目录存在\n",
"output_path = r'D:\\Idea Project\\F6+宜搭+其它(1)\\new\\文件输出\\有礼云历史维修记录——数据处理12.xlsx'\n",
"os.makedirs(os.path.dirname(output_path), exist_ok=True)\n",
"\n",
"# 输出到 Excel 文件\n",
"final_df.to_excel(output_path, index=False)"
],
"id": "da78e0ae9bf3fa4d",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Columns: Index(['ID', 'ShopID', 'FromShopID', 'CustomerType', 'Codes', 'BillCode',\n",
" 'BillDate', 'MasterMID', 'MemberID', 'MemberName', 'MemberPhone',\n",
" 'MemberDescription', 'CarID', 'CarLicencePlates', 'CarBrand',\n",
" 'CarSeries', 'CarBrandModel', 'CarColor', 'DriverName', 'DriverPhone',\n",
" 'TroubleDescriptions', 'RepairSuggestion', 'RepairType',\n",
" 'ServiceExpense', 'PartsExoense', 'PartsList', 'TaxRate', 'TaxMoney',\n",
" 'Receivable', 'Actually', 'PaidDetail', 'VouchersList', 'FreePay',\n",
" 'GivePay', 'Status', 'Description', 'Closed', 'Creator', 'Createtime',\n",
" 'Updator', 'Updatetime', 'Closedator', 'Closedatetime', 'BillBasic',\n",
" 'OthersList', 'CarAppearance', 'IsCreatedBy', 'IsChecked',\n",
" 'Customerservice', 'ifclose', 'DirectOps', 'PaiedMoneyOpeTime',\n",
" 'RebuildID', 'MoneyOpeTime', 'MoneyOper', 'IsLft', 'LftPayTime',\n",
" 'NatureOfBill', 'InsuranceCompany', 'FixedLossAmount',\n",
" 'InsuranceChargingWay', 'InsuranceStaff', 'OpeDesc', 'ServiceCost_All',\n",
" 'CommodityCost_All', 'ifStockOutFinished', 'Region',\n",
" 'is_arrears_Settle', 'Old_MemberID', 'is_bill_free', 'mall_orderid',\n",
" 'mall_ordernum', 'JianKangDangAn_uptime', 'JianKangDangAn_Index',\n",
" 'Consultant_name', 'Consultant_id', 'Balance', 'MemberName2',\n",
" 'MemberCard', 'MemberCardLevel', 'RegistrationNum', 'CarBrandModel_',\n",
" 'PaidDetail_value', 'Status_value', 'thisMonth', 'thisTimes', 'sta',\n",
" 'data', 'ResultData', 'voucherBalance', 'Carmaintainget', 'msg',\n",
" 'mem_voucherBalance', '0', 'act_res', 'Preferential_All',\n",
" 'ActuallyPaidType'],\n",
" dtype='object')\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Processing rows: 100%|██████████| 40860/40860 [00:15<00:00, 2696.79it/s]\n"
]
}
],
"execution_count": 39
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}