{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 门店审批",
   "id": "8c0d287f696c5a35"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-04-24T01:45:24.050728Z",
     "start_time": "2025-04-24T01:45:21.916224Z"
    }
   },
   "source": [
    "#!/Users/xuyeqiang/opt/miniconda3/envs/f6/bin/python3.9\n",
    "from playwright.sync_api import Playwright, sync_playwright\n",
    "import re\n",
    "import pandas as pd\n",
    "\n",
    "js = \"\"\"\n",
    "Object.defineProperties(navigator, {webdriver:{get:()=>undefined}});\n",
    "\"\"\"\n",
    "\n",
    "\n",
    "def run(playwright: Playwright) -> None:\n",
    "    browser = playwright.chromium.launch(headless=False)\n",
    "    context = browser.new_context(viewport={'width': 1700, 'height': 1080})\n",
    "\n",
    "    # Open new page\n",
    "    page = context.new_page()\n",
    "    page.add_init_script(js)  # 隐藏 webdriver属性，不然拖动滑块会失败。\n",
    "\n",
    "    # Go to https://fws.carzone365.com/#/store/quitAudit\n",
    "    page.goto(\"https://fws.carzone365.com/#/store/quitAudit\")\n",
    "\n",
    "    # Click [placeholder=\"请输入用户名\"]\n",
    "    page.click(\"[placeholder=\\\"请输入用户名\\\"]\")\n",
    "\n",
    "    # Fill [placeholder=\"请输入用户名\"]\n",
    "    page.fill(\"[placeholder=\\\"请输入用户名\\\"]\", \"17710217084\")\n",
    "\n",
    "    # Click [placeholder=\"请输入密码\"]\n",
    "    page.click(\"[placeholder=\\\"请输入密码\\\"]\")\n",
    "\n",
    "    # Fill [placeholder=\"请输入密码\"]\n",
    "    page.fill(\"[placeholder=\\\"请输入密码\\\"]\", \"123456F6!\")\n",
    "\n",
    "    \"\"\"  拖拽滑块验证  \"\"\"\n",
    "    deltaX = 50000\n",
    "    steps = 100\n",
    "    element = page.wait_for_selector(\"text=请按住滑块，拖动到最右边\")\n",
    "    boundingBox = element.bounding_box()\n",
    "    if boundingBox:\n",
    "        x = boundingBox.get('x') + boundingBox.get('width') / 2\n",
    "        y = boundingBox.get('y') + boundingBox.get('height') / 2\n",
    "        page.mouse.move(x, y)\n",
    "        page.mouse.down()\n",
    "        x1 = x + deltaX\n",
    "        page.mouse.move(x1, y, steps=steps)\n",
    "        page.mouse.up()\n",
    "        page.wait_for_timeout(1000)\n",
    "        page.click('xpath=//*[@id=\"app\"]//button[contains(@class,\"login-btn\")]')  # 登录\n",
    "        \"\"\"  开始自动化点击操作  \"\"\"\n",
    "        page.click('xpath=//*[@id=\"app\"]/section/section/aside/ul/li[2]/ul/li[2]/div/div')  # 门店审批\n",
    "        # 将每一页显示的数量设置为100\n",
    "        page.click('xpath=//*[@id=\"app\"]//input[@placeholder=\"请选择\"]')\n",
    "        page.click('xpath=//span[text()=\"100条/页\"]')\n",
    "        page.wait_for_timeout(2000)\n",
    "        page.click('xpath=//*[@id=\"app\"]/section/section/main/div/div[3]/div[2]/div[2]/button[2]/span')  # 查询\n",
    "        page.wait_for_timeout(1000)\n",
    "        # 查询出一共有多少条数据\n",
    "        input_string = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[3]/div/span[1]')\n",
    "        # 使用正则表达式提取数字部分\n",
    "        numbers = re.findall(r'\\d+', input_string)\n",
    "        # 将提取到的数字部分转换为整数列表\n",
    "        numbers = [int(num) for num in numbers][0]\n",
    "        print(f'numbers:{numbers}')\n",
    "        # 计算总页数\n",
    "        total_pages = (numbers + 100 - 1) // 100\n",
    "        # 计算最后一页条数\n",
    "        def calculate_last_page_data(total_numbers):\n",
    "            data_per_page = 100\n",
    "            last_page_data = total_numbers % data_per_page\n",
    "            return last_page_data if last_page_data != 0 else data_per_page\n",
    "        last_page_data = calculate_last_page_data(numbers)\n",
    "        print(\"最后一页显示的数据条数:\", last_page_data)\n",
    "\n",
    "        # 如果需要翻页，可以在这里添加翻页的逻辑\n",
    "        # 创建一个空列表来存储每行的数据\n",
    "        data = []\n",
    "        last_page_data_len = 100\n",
    "        for page_new in range(1, total_pages + 1):\n",
    "            print(f\"处理第 {page_new} 页的数据\")\n",
    "            if page_new == total_pages:last_page_data_len = last_page_data\n",
    "            for i in range(1,last_page_data_len + 1):\n",
    "                # 逐条获取明细\n",
    "                string_1 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[1]/div')\n",
    "                string_2 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[2]/div')\n",
    "                string_3 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[3]/div')\n",
    "                string_4 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[4]/div')\n",
    "                string_5 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[5]/div')\n",
    "                string_6 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[6]/div')\n",
    "                string_7 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[7]/div')\n",
    "                string_8 = page.text_content('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[2]/div[3]/table/tbody/tr['+str(i)+']/td[8]/div')\n",
    "                # 将数据添加到列表中\n",
    "                data.append([string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8])\n",
    "            if page_new != total_pages:\n",
    "                try:\n",
    "                    page.click('xpath=//*[@id=\"app\"]/section/section/main/div/div[4]/div[3]/div/button[2]/i')  # 下一页\n",
    "                    page.wait_for_timeout(1000)\n",
    "                except:\n",
    "                    pass\n",
    "        # 创建DataFrame\n",
    "        df = pd.DataFrame(data, columns=[\"类型\", \"门店名称\", \"门店id\", \"门店地址\", \"分类\", \"申请人\", \"状态\", \"申请时间\"])\n",
    "        df.to_excel(r\"C:\\Users\\admin\\Desktop\\门店审批明细.xlsx\")\n",
    "    page.wait_for_timeout(1000)\n",
    "    # ---------------------\n",
    "    context.close()\n",
    "    browser.close()\n",
    "\n",
    "\n",
    "with sync_playwright() as playwright:\n",
    "    run(playwright)\n"
   ],
   "outputs": [
    {
     "ename": "Error",
     "evalue": "It looks like you are using Playwright Sync API inside the asyncio loop.\nPlease use the Async API instead.",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mError\u001B[0m                                     Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[1], line 108\u001B[0m\n\u001B[0;32m    104\u001B[0m     context\u001B[38;5;241m.\u001B[39mclose()\n\u001B[0;32m    105\u001B[0m     browser\u001B[38;5;241m.\u001B[39mclose()\n\u001B[1;32m--> 108\u001B[0m \u001B[38;5;28;01mwith\u001B[39;00m sync_playwright() \u001B[38;5;28;01mas\u001B[39;00m playwright:\n\u001B[0;32m    109\u001B[0m     run(playwright)\n",
      "File \u001B[1;32mD:\\ProgramTools\\Anaconda\\Lib\\site-packages\\playwright\\sync_api\\_context_manager.py:47\u001B[0m, in \u001B[0;36mPlaywrightContextManager.__enter__\u001B[1;34m(self)\u001B[0m\n\u001B[0;32m     45\u001B[0m             \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_own_loop \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[0;32m     46\u001B[0m         \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_loop\u001B[38;5;241m.\u001B[39mis_running():\n\u001B[1;32m---> 47\u001B[0m             \u001B[38;5;28;01mraise\u001B[39;00m Error(\n\u001B[0;32m     48\u001B[0m \u001B[38;5;250m                \u001B[39m\u001B[38;5;124;03m\"\"\"It looks like you are using Playwright Sync API inside the asyncio loop.\u001B[39;00m\n\u001B[0;32m     49\u001B[0m \u001B[38;5;124;03mPlease use the Async API instead.\"\"\"\u001B[39;00m\n\u001B[0;32m     50\u001B[0m             )\n\u001B[0;32m     52\u001B[0m         \u001B[38;5;66;03m# Create a new fiber for the protocol dispatcher. It will be pumping events\u001B[39;00m\n\u001B[0;32m     53\u001B[0m         \u001B[38;5;66;03m# until the end of times. We will pass control to that fiber every time we\u001B[39;00m\n\u001B[0;32m     54\u001B[0m         \u001B[38;5;66;03m# block while waiting for a response.\u001B[39;00m\n\u001B[0;32m     55\u001B[0m         \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mgreenlet_main\u001B[39m() \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n",
      "\u001B[1;31mError\u001B[0m: It looks like you are using Playwright Sync API inside the asyncio loop.\nPlease use the Async API instead."
     ]
    }
   ],
   "execution_count": 1
  }
 ],
 "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
}
