{"id":1913,"date":"2026-06-26T13:48:33","date_gmt":"2026-06-26T13:48:33","guid":{"rendered":"https:\/\/aabbee.cafe24.com\/?p=1913"},"modified":"2026-06-26T14:02:46","modified_gmt":"2026-06-26T14:02:46","slug":"job-crawler","status":"publish","type":"post","link":"https:\/\/coalacoding.com\/?p=1913","title":{"rendered":"\uad6c\uc778\uc5c5\uccb4 \ub370\uc774\ud130 \uc218\uc9d1 \ud06c\ub864\ub7ec \ub9cc\ub4e4\uae30 (\ubc14\uc774\ube0c \ucf54\ub529)"},"content":{"rendered":"<blockquote>\n<p>Claude\ub098 Gemini \uac19\uc740 AI\uc5d0\uac8c \uc2dc\ucf1c\uc11c \uc7a1\ucf54\ub9ac\uc544\u00b7\uc0ac\ub78c\uc778 \ucc44\uc6a9\uacf5\uace0 \ud06c\ub864\ub7ec\ub97c \uc9c1\uc811 \uc2e4\ud589\ud574 \ubcf8\ub2e4. \ud30c\uc774\uc36c\uc744 \ud55c \uc904\ub3c4 \uc368 \ubcf8 \uc801\uc774 \uc5c6\uc5b4\ub3c4 \ud504\ub86c\ud504\ud2b8\ub9cc \uc798 \uc8fc\uba74 \uc644\uc131\ub41c Excel \ud30c\uc77c\uc744 \ubc1b\uc744 \uc218 \uc788\ub2e4.<\/p>\n<\/blockquote>\n<h2>1. \uc900\ube44\ubb3c<\/h2>\n<table>\n<thead>\n<tr>\n<th>\ud56d\ubaa9<\/th>\n<th>\uc124\uba85<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\ucef4\ud4e8\ud130<\/td>\n<td>\ub9e5\u00b7\uc708\ub3c4\uc6b0\u00b7\ub9ac\ub205\uc2a4 \ubaa8\ub450 \uac00\ub2a5<\/td>\n<\/tr>\n<tr>\n<td>Python 3.10+<\/td>\n<td><a href=\"https:\/\/www.python.org\/downloads\/\">python.org<\/a>\uc5d0\uc11c \uc124\uce58<\/td>\n<\/tr>\n<tr>\n<td>AI \ub3c4\uad6c<\/td>\n<td><a href=\"https:\/\/claude.ai\">Claude<\/a> \ub610\ub294 Gemini CLI<\/td>\n<\/tr>\n<tr>\n<td>VS Code<\/td>\n<td><a href=\"https:\/\/code.visualstudio.com\/\">code.visualstudio.com<\/a> (\uc120\ud0dd)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>2. \ud30c\uc774\uc36c &quot;\uac00\uc0c1\ud658\uacbd&quot; \ub9cc\ub4e4\uae30<\/h2>\n<p>\ud504\ub85c\uc81d\ud2b8\ub9c8\ub2e4 \ub3c5\ub9bd\ub41c \ud30c\uc774\uc36c \ud658\uacbd\uc744 \uc4f0\uba74 \ud328\ud0a4\uc9c0 \ucda9\ub3cc\uc744 \ub9c9\uc744 \uc218 \uc788\ub2e4. \uc0c1\uc790\ub97c \ub530\ub85c \ub450\ub294 \ub290\ub08c\uc774\ub2e4.<\/p>\n<p><MdxNotice type=\"note\" title=\"macOS \/ Linux\"><\/p>\n<pre><code class=\"language-bash\"># 1) \uc791\uc5c5 \ud3f4\ub354 \ub9cc\ub4e4\uae30\nmkdir ~\/crawler &amp;&amp; cd ~\/crawler\n\n# 2) \uac00\uc0c1\ud658\uacbd \uc0dd\uc131\npython3 -m venv .venv\n\n# 3) \ud65c\uc131\ud654\nsource .venv\/bin\/activate\n\n# \ud504\ub86c\ud504\ud2b8 \uc55e\uc5d0 (.venv) \uac00 \ubd99\uc73c\uba74 \uc131\uacf5\n<\/code><\/pre>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"Windows (PowerShell)\"><\/p>\n<pre><code class=\"language-powershell\"># 1) \uc791\uc5c5 \ud3f4\ub354 \ub9cc\ub4e4\uae30\nmkdir $HOMEcrawler\ncd $HOMEcrawler\n\n# 2) \uac00\uc0c1\ud658\uacbd \uc0dd\uc131\npython -m venv .venv\n\n# 3) \ud65c\uc131\ud654\n.venvScriptsActivate.ps1\n\n# \uc2e4\ud589 \uc815\ucc45 \uc624\ub958\uac00 \ub098\uba74 \ud55c \ubc88\ub9cc:\n# Set-ExecutionPolicy -Scope CurrentUser RemoteSigned\n<\/code><\/pre>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"Windows (CMD)\"><\/p>\n<pre><code class=\"language-cmd\">mkdir %USERPROFILE%crawler\ncd %USERPROFILE%crawler\n\npython -m venv .venv\n.venvScriptsactivate.bat\n<\/code><\/pre>\n<p><\/MdxNotice><\/p>\n<h3>2-1. \ud328\ud0a4\uc9c0 \uc124\uce58<\/h3>\n<p>\uac00\uc0c1\ud658\uacbd\uc774 \ud65c\uc131\ud654\ub41c \uc0c1\ud0dc\uc5d0\uc11c \uc2e4\ud589\ud55c\ub2e4.<\/p>\n<pre><code class=\"language-bash\">pip install requests beautifulsoup4 lxml openpyxl\n<\/code><\/pre>\n<p><MdxNotice type=\"warning\" title=\"\uc624\ub958\uac00 \ub098\uba74\"><br \/>\n`pip` \uba85\ub839\uc774 \uc5c6\ub2e4\ub294 \uc624\ub958\uac00 \ub098\uba74 \uac00\uc0c1\ud658\uacbd \ud65c\uc131\ud654\uac00 \uc548 \ub41c \uac83\uc774\ub2e4.<br \/>\n\ud504\ub86c\ud504\ud2b8 \uc55e\uc5d0 `(.venv)` \uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.<br \/>\n<\/MdxNotice><\/p>\n<h2>3. AI \ub3c4\uad6c \uc900\ube44<\/h2>\n<p><MdxNotice type=\"note\" title=\"Gemini CLI (\ud130\ubbf8\ub110\uc5d0\uc11c \uc4f0\uae30)\"><\/p>\n<pre><code class=\"language-bash\"># \uc124\uce58 (Node.js \ud544\uc694)\nnpm install -g @google\/gemini-cli\n\n# \ub85c\uadf8\uc778 (\ube0c\ub77c\uc6b0\uc800\uac00 \uc5f4\ub9b0\ub2e4)\ngemini auth login\n\n# \uc2e4\ud589 \u2014 \ub300\ud654\ucc3d\uc774 \uc5f4\ub9b0\ub2e4\ngemini\n<\/code><\/pre>\n<p><strong>\uc7a5\uc810<\/strong>: \ud130\ubbf8\ub110 \uc548\uc5d0\uc11c \ud30c\uc77c \uc77d\uae30\u00b7\uc4f0\uae30\u00b7\uc2e4\ud589\uae4c\uc9c0 AI\uac00 \ud574\uc900\ub2e4.<br \/>\n<strong>\ub2e8\uc810<\/strong>: Node.js \uc124\uce58 \ud544\uc694.<\/p>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"Claude (\uc6f9)\"><\/p>\n<p><a href=\"https:\/\/claude.ai\">claude.ai<\/a> \uc5d0\uc11c \ubc14\ub85c \uc4f8 \uc218 \uc788\ub2e4.<\/p>\n<ol>\n<li>\uac00\uc785 \ud6c4 \uc0c8 \ub300\ud654 \uc2dc\uc791<\/li>\n<li>\uc544\ub798 \ud504\ub86c\ud504\ud2b8\ub97c \ubcf5\uc0ac\ud574 \ubd99\uc5ec\ub123\uae30<\/li>\n<li>\ubc1b\uc740 \ucf54\ub4dc\ub97c <code>crawler.py<\/code> \ub85c \uc800\uc7a5<\/li>\n<li>\ud130\ubbf8\ub110\uc5d0\uc11c <code>python crawler.py<\/code> \uc2e4\ud589<\/li>\n<\/ol>\n<p><strong>\uc7a5\uc810<\/strong>: \uc124\uce58 \ubd88\ud544\uc694, \uae34 \ucf54\ub4dc\ub3c4 \uc798 \uc4f4\ub2e4.<br \/>\n<strong>\ub2e8\uc810<\/strong>: \ud30c\uc77c \uc800\uc7a5\u00b7\uc2e4\ud589\uc740 \uc9c1\uc811 \ud574\uc57c \ud55c\ub2e4.<\/p>\n<p><\/MdxNotice><\/p>\n<h2>4. \uc7a1\ucf54\ub9ac\uc544 \ud06c\ub864\ub7ec \ud504\ub86c\ud504\ud2b8<\/h2>\n<p><MdxAccordion title=\"\uc804\uccb4 \ud504\ub86c\ud504\ud2b8 (\ubcf5\uc0ac\uc6a9)\"><\/p>\n<pre><code class=\"language-text\">\uc5ed\ud560: 30\ub144\ucc28 \ud480\uc2a4\ud0dd \uac1c\ubc1c\uc790\n\n\uc791\uc5c5: \uc7a1\ucf54\ub9ac\uc544 \ucc44\uc6a9\uacf5\uace0\ub97c \uc790\ub3d9 \uc218\uc9d1\ud574 Excel \ud30c\uc77c\ub85c \uc800\uc7a5\ud558\ub294\n     \ud30c\uc774\uc36c \ud06c\ub864\ub7ec\ub97c \uc791\uc131\ud55c\ub2e4.\n\n\uc218\uc9d1 \uc870\uac74:\n- \uc9c1\ubb34 \ucf54\ub4dc(duty): 1000255(\uc6f9\ub514\uc790\uc774\ub108), 1000256(UI\u00b7UX\ub514\uc790\uc774\ub108)\n  \u2192 CONFIG \ub515\uc154\ub108\ub9ac\ub85c \ub9cc\ub4e4\uc5b4 \uc27d\uac8c \ubcc0\uacbd\ud560 \uc218 \uc788\uac8c \ud55c\ub2e4\n- \uc9c0\uc5ed: \uc11c\uc6b8 \uc804\uc9c0\uc5ed(local=I010001)\n- \uacbd\ub825: \uc2e0\uc785(careerType=1)\n- \ud655\uc778\ud55c \uacf5\uace0 \uc81c\uc678(filter=1)\n\n\uc218\uc9d1 \ubc29\ubc95:\n- URL: https:\/\/www.jobkorea.co.kr\/Search\/\n- \ud398\uc774\uc9c0 \ud30c\ub77c\ubbf8\ud130 \uc774\ub984\uc740 Page_No (\ud398\uc774\uc9c0\ub2f9 20\uac1c)\n- HTML \uc548 self.__next_f.push([1,&quot;...&quot;]) \ube14\ub85d\uc5d0\uc11c JSON \ub370\uc774\ud130\ub97c \uc774\uc911 \ub514\ucf54\ub529\n- &quot;JOB_LIST queryKey&quot; \uc774\uc804\uc5d0 \uc704\uce58\ud55c \ub9c8\uc9c0\ub9c9 totalElements\ub97c \uc120\ud0dd\n  (\uac00\uc7a5 \ud070 \uac12\uc740 \uc804\uccb4 \uacf5\uace0 \uc218 69\ub9cc\uac74\uc774\ub77c \uc798\ubabb\ub41c \uac12\uc774\ub2e4)\n\n\ud6c4\ucc98\ub9ac \ud544\ud130:\n- areaCodeList\uc5d0 \uc11c\uc6b8 \uad6c \ucf54\ub4dc(I010~I250)\uac00 \uc788\ub294 \uacf5\uace0\ub9cc \ub0a8\uae34\ub2e4\n  (areaCodeList\uac00 None\uc77c \uc218 \uc788\uc73c\ub2c8 &quot;or []&quot; \ub85c \ubc29\uc5b4)\n- receptionOptionType \ub9c8\uc9c0\ub9c9 \uc790\ub9ac\uac00 &quot;1&quot;\uc774\uba74 \ud648\ud398\uc774\uc9c0 \uc9c0\uc6d0\uc774\ub77c \uc81c\uc678\n- ThreadPoolExecutor(max_workers=8)\ub85c \uc9c1\uc6d0\uc218 \ubcd1\ub82c \uc870\ud68c\n- \uc9c1\uc6d0\uc218 10\uba85 \uc774\uc0c1\ub9cc \ub0a8\uae34\ub2e4 (\ubbf8\ud655\uc778\uc740 \ud3ec\ud568)\n\n\ucd9c\ub825:\n- openpyxl\ub85c Excel \uc800\uc7a5: \ud5e4\ub354 \uace0\uc815\u00b7\uc790\ub3d9\ud544\ud130\u00b7\ud558\uc774\ud37c\ub9c1\ud06c \ud3ec\ud568\n- \ud30c\uc77c\uba85: \uc7a1\ucf54\ub9ac\uc544_YYYYMMDD.xlsx\n- \uceec\ub7fc: \uacf5\uace0\uc81c\ubaa9, \ud68c\uc0ac\uba85, \uc9c1\uc6d0\uc218, \uc9c0\uc5ed, \ub9c8\uac10\uc77c, \ub9c1\ud06c\n\n\uc81c\uc57d:\n- \uc694\uccad \uac04 time.sleep(0.3) \ub51c\ub808\uc774\n- User-Agent \ud5e4\ub354 \uc2e4\uc81c \ube0c\ub77c\uc6b0\uc800 \uac12\n- \ud30c\uc77c\uc740 \ud558\ub098\ub85c (crawler.py)\n\n\uc791\uc131 \ud6c4 \uc7a0\uc7ac \ubc84\uadf8\ub97c \uac80\ud1a0\ud558\uace0 \uc2e4\ud589 \ubc29\ubc95\uc744 \uc54c\ub824\ub2ec\ub77c.\n<\/code><\/pre>\n<p><\/MdxAccordion><MdxNotice type=\"tip\" title=\"\ud504\ub86c\ud504\ud2b8 \uc218\uc815 \ud301\"><br \/>\n\uc9c1\ubb34\ub098 \uc9c0\uc5ed\uc744 \ubc14\uafb8\uace0 \uc2f6\uc73c\uba74 \ud504\ub86c\ud504\ud2b8 <strong>\ub9e8 \uc704 \uc870\uac74 \ubd80\ubd84\ub9cc<\/strong> \ubc14\uafd4\uc11c \ub2e4\uc2dc \ubcf4\ub0b4\uba74 \ub41c\ub2e4. \uc608\ub97c \ub4e4\uc5b4 &#8220;\ud504\ub860\ud2b8\uc5d4\ub4dc\uac1c\ubc1c\uc790(1000230)\ub9cc&#8221; \ub610\ub294 &#8220;\uacbd\ub825 3\ub144 \uc774\uc0c1(careerType=2)&#8221; \uc73c\ub85c.<br \/>\n<\/MdxNotice><\/p>\n<h3>4-1. \uc8fc\uc694 \uc9c1\ubb34 \ucf54\ub4dc \ubaa9\ub85d<\/h3>\n<table>\n<thead>\n<tr>\n<th>\ucf54\ub4dc<\/th>\n<th>\uc9c1\ubb34<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1000248<\/td>\n<td>\uadf8\ub798\ud53d\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000252<\/td>\n<td>\uad11\uace0\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000253<\/td>\n<td>\uc2dc\uac01\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000255<\/td>\n<td>\uc6f9\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000256<\/td>\n<td>UI\u00b7UX\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000258<\/td>\n<td>\ud3b8\uc9d1\ub514\uc790\uc774\ub108<\/td>\n<\/tr>\n<tr>\n<td>1000250<\/td>\n<td>\uc77c\ub7ec\uc2a4\ud2b8\ub808\uc774\ud130<\/td>\n<\/tr>\n<tr>\n<td>1000230<\/td>\n<td>\ud504\ub860\ud2b8\uc5d4\ub4dc\uac1c\ubc1c\uc790<\/td>\n<\/tr>\n<tr>\n<td>1000245<\/td>\n<td>\uc6f9\ud37c\ube14\ub9ac\uc154<\/td>\n<\/tr>\n<tr>\n<td>1000279<\/td>\n<td>\uc6f9\uae30\ud68d<\/td>\n<\/tr>\n<tr>\n<td>1000188<\/td>\n<td>PL\u00b7PM\u00b7PO<\/td>\n<\/tr>\n<tr>\n<td>1000388<\/td>\n<td>\uc601\uc0c1\ud3b8\uc9d1\uc790<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>5. \uc0ac\ub78c\uc778 \ud06c\ub864\ub7ec \ud504\ub86c\ud504\ud2b8<\/h2>\n<p><MdxAccordion title=\"\uc804\uccb4 \ud504\ub86c\ud504\ud2b8 (\ubcf5\uc0ac\uc6a9)\"><\/p>\n<pre><code class=\"language-text\">\uc5ed\ud560: 30\ub144\ucc28 \ud480\uc2a4\ud0dd \uac1c\ubc1c\uc790\n\n\uc791\uc5c5: \uc0ac\ub78c\uc778 \ucc44\uc6a9\uacf5\uace0\ub97c \uc790\ub3d9 \uc218\uc9d1\ud574 Excel \ud30c\uc77c\ub85c \uc800\uc7a5\ud558\ub294\n     \ud30c\uc774\uc36c \ud06c\ub864\ub7ec\ub97c \uc791\uc131\ud55c\ub2e4.\n\n\uc218\uc9d1 \uc870\uac74:\n- \uc9c1\ubb34 \ucf54\ub4dc(cat_kewd): 1502(\uc6f9\ub514\uc790\uc778), 1690(UI\/UX)\n  \u2192 CONFIG \ub515\uc154\ub108\ub9ac\ub85c \ub9cc\ub4e4\uc5b4 \uc27d\uac8c \ubcc0\uacbd\ud560 \uc218 \uc788\uac8c \ud55c\ub2e4\n- \uc9c0\uc5ed: \uc11c\uc6b8 \uc804\uc9c0\uc5ed(loc_mcd=101000)\n- \uacbd\ub825: \uc2e0\uc785(exp_cd=1)\n\n\uc218\uc9d1 \ubc29\ubc95:\n- URL: https:\/\/www.saramin.co.kr\/zf_user\/search\/recruit\n- \ud398\uc774\uc9c0 \ud30c\ub77c\ubbf8\ud130 \uc774\ub984\uc740 recruitPage (\uc8fc\uc758: &quot;page&quot;\uac00 \uc544\ub2c8\ub2e4!)\n- \ud398\uc774\uc9c0\ub2f9 40\uac1c\n- BeautifulSoup\uc73c\ub85c .item_recruit \uc5d8\ub9ac\uba3c\ud2b8\ub97c \ud30c\uc2f1\n- \uacf5\uace0\ub9c8\ub2e4 rec_idx, title, company, csn, conditions \ucd94\ucd9c\n- .sri_btn_homepage_apply \uc5d8\ub9ac\uba3c\ud2b8\uac00 \uc788\uc73c\uba74 \ud648\ud398\uc774\uc9c0 \uc9c0\uc6d0(\uc81c\uc678 \ub300\uc0c1)\n\n\ud6c4\ucc98\ub9ac \ud544\ud130:\n- conditions[0]\uc774 &quot;\uc11c\uc6b8\uc804\uccb4&quot;\uc778 \uacf5\uace0\ub294 \uc81c\uc678 (\uad6c \ub2e8\uc704 \uacf5\uace0\ub9cc \ub0a8\uae40)\n- \ud648\ud398\uc774\uc9c0 \uc9c0\uc6d0 \uacf5\uace0\ub294 \uc81c\uc678\n- \uae30\uc5c5\uc815\ubcf4 \ud398\uc774\uc9c0(csn \ud544\uc694)\uc5d0\uc11c \uc0ac\uc6d0\uc218 \uc870\ud68c:\n  URL: https:\/\/www.saramin.co.kr\/zf_user\/company-info\/view?csn={csn}\n  p.company_summary_desc \ud14d\uc2a4\ud2b8\uac00 &quot;\uc0ac\uc6d0\uc218&quot;\uc778 li\uc5d0\uc11c strong.company_summary_tit\n- ThreadPoolExecutor(max_workers=8)\ub85c \ubcd1\ub82c \uc870\ud68c\n- \uc9c1\uc6d0\uc218 10\uba85 \uc774\uc0c1\ub9cc \ub0a8\uae34\ub2e4\n\n\ucd9c\ub825:\n- openpyxl\ub85c Excel \uc800\uc7a5: \ud5e4\ub354 \uace0\uc815\u00b7\uc790\ub3d9\ud544\ud130\u00b7\ud558\uc774\ud37c\ub9c1\ud06c \ud3ec\ud568\n- \ud30c\uc77c\uba85: \uc0ac\ub78c\uc778_YYYYMMDD.xlsx\n- \uceec\ub7fc: \uacf5\uace0\uc81c\ubaa9, \ud68c\uc0ac\uba85, \uc9c1\uc6d0\uc218, \uc9c0\uc5ed, \uace0\uc6a9\ud615\ud0dc, \ub9c8\uac10\uc77c, \ub9c1\ud06c\n\n\uc81c\uc57d:\n- \uc694\uccad \uac04 time.sleep(0.3) \ub51c\ub808\uc774\n- User-Agent \ud5e4\ub354 \uc2e4\uc81c \ube0c\ub77c\uc6b0\uc800 \uac12\n- \ud30c\uc77c\uc740 \ud558\ub098\ub85c (crawler.py)\n\n\uc791\uc131 \ud6c4 \uc7a0\uc7ac \ubc84\uadf8\ub97c \uac80\ud1a0\ud558\uace0 \uc2e4\ud589 \ubc29\ubc95\uc744 \uc54c\ub824\ub2ec\ub77c.\n<\/code><\/pre>\n<p><\/MdxAccordion><\/p>\n<h3>5-1. \uc8fc\uc694 cat_kewd \ucf54\ub4dc \ubaa9\ub85d<\/h3>\n<table>\n<thead>\n<tr>\n<th>\ucf54\ub4dc<\/th>\n<th>\uc9c1\ubb34<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1484<\/td>\n<td>\uadf8\ub798\ud53d\ub514\uc790\uc778<\/td>\n<\/tr>\n<tr>\n<td>1483<\/td>\n<td>\uad11\uace0\ub514\uc790\uc778<\/td>\n<\/tr>\n<tr>\n<td>1496<\/td>\n<td>\uc2dc\uac01\ub514\uc790\uc778<\/td>\n<\/tr>\n<tr>\n<td>1502<\/td>\n<td>\uc6f9\ub514\uc790\uc778<\/td>\n<\/tr>\n<tr>\n<td>1519<\/td>\n<td>\ud3b8\uc9d1\ub514\uc790\uc778<\/td>\n<\/tr>\n<tr>\n<td>1504<\/td>\n<td>\uc77c\ub7ec\uc2a4\ud2b8\ub808\uc774\ud130<\/td>\n<\/tr>\n<tr>\n<td>1690<\/td>\n<td>UI\/UX<\/td>\n<\/tr>\n<tr>\n<td>92<\/td>\n<td>\ud504\ub860\ud2b8\uc5d4\ub4dc<\/td>\n<\/tr>\n<tr>\n<td>91<\/td>\n<td>\ud37c\ube14\ub9ac\uc154<\/td>\n<\/tr>\n<tr>\n<td>1637<\/td>\n<td>\uc6f9\uae30\ud68d<\/td>\n<\/tr>\n<tr>\n<td>1649<\/td>\n<td>PM<\/td>\n<\/tr>\n<tr>\n<td>1373<\/td>\n<td>\uc601\uc0c1\ud3b8\uc9d1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>6. \ud1b5\ud569 \ud06c\ub864\ub7ec \ud504\ub86c\ud504\ud2b8 (\uc7a1\ucf54\ub9ac\uc544 + \uc0ac\ub78c\uc778)<\/h2>\n<p>\ub450 \uc0ac\uc774\ud2b8 \uacb0\uacfc\ub97c \ud558\ub098\uc758 Excel\ub85c \ud569\uce58\uace0 \uc2f6\uc744 \ub54c \uc4f4\ub2e4.<\/p>\n<p><MdxAccordion title=\"\ud1b5\ud569 \ud504\ub86c\ud504\ud2b8 (\ubcf5\uc0ac\uc6a9)\"><\/p>\n<pre><code class=\"language-text\">\uc5ed\ud560: 30\ub144\ucc28 \ud480\uc2a4\ud0dd \uac1c\ubc1c\uc790\n\n\uc791\uc5c5: \uc7a1\ucf54\ub9ac\uc544\uc640 \uc0ac\ub78c\uc778\uc5d0\uc11c \uac19\uc740 \uc870\uac74\uc758 \ucc44\uc6a9\uacf5\uace0\ub97c \uc218\uc9d1\ud55c \ub4a4\n     \uacb0\uacfc\ub97c \ud558\ub098\uc758 Excel\uc5d0 \ud1b5\ud569\ud574 \uc800\uc7a5\ud55c\ub2e4.\n\n\uc218\uc9d1 \uc870\uac74:\n- \uc9c1\ubb34: \uc6f9\ub514\uc790\uc774\ub108 + UI\/UX\n  * \uc7a1\ucf54\ub9ac\uc544 duty: 1000255, 1000256\n  * \uc0ac\ub78c\uc778 cat_kewd: 1502, 1690\n- \uc9c0\uc5ed: \uc11c\uc6b8 (\uc11c\uc6b8\uc804\uccb4 \ud45c\uae30 \uacf5\uace0 \uc81c\uc678 \u2192 \uad6c \ub2e8\uc704\ub9cc)\n- \uacbd\ub825: \uc2e0\uc785\n- \ud648\ud398\uc774\uc9c0 \uc9c0\uc6d0 \uc81c\uc678\n- \uc0ac\uc6d0\uc218 10\uba85 \uc774\uc0c1\n\n\ubaa8\ub4c8 \uad6c\uc870 (\ud30c\uc77c 3\uac1c):\n1. jobkorea.py  \u2014 \uc7a1\ucf54\ub9ac\uc544 \ud06c\ub864\ub7ec\n2. saramin.py   \u2014 \uc0ac\ub78c\uc778 \ud06c\ub864\ub7ec\n3. merge.py     \u2014 \uc9c4\uc785\uc810. \ub450 \ud06c\ub864\ub7ec\ub97c \ud638\ucd9c\ud55c \ub4a4 \uacb0\uacfc\ub97c \ud569\uccd0 Excel \uc800\uc7a5\n\n\ud1b5\ud569 \uc2dc \uc2a4\ud0a4\ub9c8:\n- \uacf5\ud1b5 \uceec\ub7fc: \ucd9c\ucc98(jobkorea\/saramin), \uacf5\uace0\uc81c\ubaa9, \ud68c\uc0ac\uba85, \uc9c1\uc6d0\uc218,\n            \uc9c0\uc5ed, \uacbd\ub825, \ub9c8\uac10\uc77c, \ub9c1\ud06c\n- \uc911\ubcf5 \ud310\ub2e8: (\ud68c\uc0ac\uba85 + \uacf5\uace0\uc81c\ubaa9) \uc774 \uac19\uc73c\uba74 \uc911\ubcf5\n  \u2192 \uc911\ubcf5\uc740 &#39;\ucd9c\ucc98&#39; \uceec\ub7fc\uc5d0 &quot;jobkorea, saramin&quot; \ucc98\ub7fc \ud568\uaed8 \ud45c\uae30\n\n\ucd9c\ub825:\n- \ud30c\uc77c\uba85: \ud1b5\ud569\ucc44\uc6a9\uacf5\uace0_YYYYMMDD.xlsx\n- \uc2dc\ud2b8 3\uac1c: [\uc804\uccb4\ud1b5\ud569], [\uc7a1\ucf54\ub9ac\uc544\uc6d0\ubcf8], [\uc0ac\ub78c\uc778\uc6d0\ubcf8]\n- \uc804\uccb4\ud1b5\ud569 \uc2dc\ud2b8\ub294 \uc9c1\uc6d0\uc218 \uc624\ub984\ucc28\uc21c \uc815\ub82c\n- \uc0c1\uc704 \ud0ed\uc5d0 \uc694\uc57d \uc815\ubcf4(\uc218\uc9d1\uc77c\u00b7\ucd1d\uac74\uc218\u00b7\uc0ac\uc774\ud2b8\ubcc4 \uac74\uc218)\n\n\uc81c\uc57d:\n- \uc0ac\uc774\ud2b8\ubcc4 \ud06c\ub864\ub7ec\ub294 \ubcd1\ub82c\uc774 \uc544\ub2cc \uc21c\ucc28 \uc2e4\ud589 (\ucc28\ub2e8 \ubc29\uc9c0)\n- \uac19\uc740 \uc0ac\uc774\ud2b8 \uc548\uc5d0\uc11c\ub9cc ThreadPoolExecutor \uc0ac\uc6a9\n- \uc791\uc131 \ud6c4 \uc7a0\uc7ac \ubc84\uadf8 \uac80\ud1a0 \ubc0f \uc2e4\ud589 \ubc29\ubc95 \uc548\ub0b4\n<\/code><\/pre>\n<p><\/MdxAccordion><\/p>\n<h2>7. \uc2e4\ud589\ud558\uae30<\/h2>\n<p>AI\uc5d0\uac8c\uc11c \ubc1b\uc740 \ucf54\ub4dc\ub97c <code>crawler.py<\/code> \ub85c \uc800\uc7a5\ud55c \ub4a4 \uc2e4\ud589\ud55c\ub2e4.<\/p>\n<pre><code class=\"language-bash\"># \uac00\uc0c1\ud658\uacbd\uc774 \ud65c\uc131\ud654\ub41c \uc0c1\ud0dc\uc5d0\uc11c\npython crawler.py\n<\/code><\/pre>\n<p>\uc9c4\ud589 \uc0c1\ud669\uc774 \ud130\ubbf8\ub110\uc5d0 \ucd9c\ub825\ub41c\ub2e4. \uc885\ub8cc\ub418\uba74 \uac19\uc740 \ud3f4\ub354\uc5d0 Excel \ud30c\uc77c\uc774 \uc0dd\uae34\ub2e4.<\/p>\n<pre><code class=\"language-text\">============================================================\n  \uc7a1\ucf54\ub9ac\uc544 \uc9c1\ubb34\ubcc4 \ucc44\uc6a9\uacf5\uace0 \ud06c\ub864\ub7ec\n============================================================\n  [\ud398\uc774\uc9c0   1\/40] 20\uac1c (20\uac1c \uc2e0\uaddc) | \ub204\uc801   20\uac1c\n  [\ud398\uc774\uc9c0   2\/40] 20\uac1c (20\uac1c \uc2e0\uaddc) | \ub204\uc801   40\uac1c\n  ...\n  \u2192 \uc218\uc9d1 \uc644\ub8cc: 782\uac1c\n  \u2192 \uc11c\uc6b8 \uad6c \ud544\ud130 \ud6c4: 523\uac1c\n  \u2192 \ud648\ud398\uc774\uc9c0\uc9c0\uc6d0 \uc81c\uc678 \ud6c4: 498\uac1c\n  \uc9c1\uc6d0\uc218 \ubcd1\ub82c \uc870\ud68c (workers=8)...\n    \uc9c1\uc6d0\uc218 \ud655\uc778 100\/498\n    ...\n  \u2192 \ucd5c\uc885 471\uac1c\n  Excel \uc800\uc7a5: \uc7a1\ucf54\ub9ac\uc544_20260417.xlsx\n<\/code><\/pre>\n<h2>8. \uc624\ub958\uac00 \ub098\uba74 AI\uc5d0\uac8c \ub2e4\uc2dc \uc2dc\ud0a4\uae30<\/h2>\n<p>\uc5d0\ub7ec \uba54\uc2dc\uc9c0\ub97c \uadf8\ub300\ub85c \ubcf5\uc0ac\ud574 AI\uc5d0\uac8c \ubcf4\ub0b4\uba74 \ub41c\ub2e4.<\/p>\n<p><MdxAccordion title=\"\uc608\uc2dc 1: TypeError: NoneType is not iterable\"><\/p>\n<pre><code class=\"language-text\">\uc544\ub798 \uc5d0\ub7ec\ub97c \uc218\uc815\ud574\ub77c:\n\nTraceback (most recent call last):\n  File &quot;crawler.py&quot;, line 123, in has_gu_address\n    return any(c in SEOUL_GU_CODES for c in codes)\nTypeError: &#39;NoneType&#39; object is not iterable\n\n\ubb38\uc81c\uac00 \ub41c \uc904: codes = job.get(&quot;areaCodeList&quot;, [])\n<\/code><\/pre>\n<p>AI\uac00 <code>job.get(&quot;areaCodeList&quot;) or []<\/code> \ub85c \uc218\uc815\ud574 \uc900\ub2e4.<\/p>\n<p><\/MdxAccordion><MdxAccordion title=\"\uc608\uc2dc 2: \ud398\uc774\uc9c0\ub97c \ub118\uaca8\ub3c4 \uac19\uc740 \ub370\uc774\ud130\"><\/p>\n<pre><code class=\"language-text\">\uc0ac\ub78c\uc778 \ud06c\ub864\ub7ec\uac00 \ud398\uc774\uc9c0\ub97c \ub118\uaca8\ub3c4 \uac19\uc740 \uacf5\uace0\ub9cc \ubc18\ubcf5\ud574\uc11c \uc218\uc9d1\ud55c\ub2e4.\nparams\uc5d0 &quot;page&quot;\ub97c \uc4f0\uace0 \uc788\ub294\ub370 \ubb38\uc81c\uc778\uc9c0 \ud655\uc778\ud574\ub77c.\n<\/code><\/pre>\n<p>AI\uac00 <code>page<\/code> \u2192 <code>recruitPage<\/code> \ub85c \uc218\uc815\ud574 \uc900\ub2e4.<\/p>\n<p><\/MdxAccordion><MdxAccordion title=\"\uc608\uc2dc 3: \uc218\uc9d1 \uac74\uc218\uac00 \ube44\uc815\uc0c1\uc73c\ub85c \ud06c\uac8c \ub098\uc628\ub2e4\"><\/p>\n<pre><code class=\"language-text\">\uc7a1\ucf54\ub9ac\uc544 \ud06c\ub864\ub7ec\uc5d0\uc11c \ucd1d \uac74\uc218\uac00 69\ub9cc\uac74\uc73c\ub85c \ub098\uc624\ub294\ub370 \uc2e4\uc81c\ub294 \ud6e8\uc52c \uc801\ub2e4.\n__next_f.push \ube14\ub85d\uc5d0\uc11c totalElements\ub97c \uc5ec\ub7ec \uac1c \ucc3e\uc740 \ub4a4\n&quot;\uac00\uc7a5 \ud070 \uac12&quot;\uc744 \uc120\ud0dd\ud558\uace0 \uc788\ub294\ub370 \uc774\uac8c \uc798\ubabb\ub41c \uac83 \uac19\ub2e4.\n&quot;JOB_LIST queryKey \uc774\uc804\uc5d0 \uc704\uce58\ud55c \ub9c8\uc9c0\ub9c9 totalElements&quot;\ub97c \uc4f0\ub3c4\ub85d \uace0\uccd0\ub77c.\n<\/code><\/pre>\n<p>AI\uac00 \ud30c\uc2f1 \ub85c\uc9c1\uc744 \uace0\uce5c\ub2e4.<\/p>\n<p><\/MdxAccordion><MdxAccordion title=\"\uc608\uc2dc 4: \uc694\uccad\uc774 \ucc28\ub2e8\ub41c\ub2e4 (429 \uc5d0\ub7ec)\"><\/p>\n<pre><code class=\"language-text\">\ud06c\ub864\ub9c1 \uc911 429 Too Many Requests \uc5d0\ub7ec\uac00 \ub72c\ub2e4.\n- time.sleep \uac04\uaca9\uc744 0.3\ucd08\uc5d0\uc11c 0.8\ucd08\ub85c \ub298\ub824\ub77c\n- ThreadPoolExecutor max_workers\ub97c 8\uc5d0\uc11c 4\ub85c \uc904\uc5ec\ub77c\n- User-Agent \ud5e4\ub354\ub97c \ucd5c\uc2e0 \ud06c\ub86c \uac12\uc73c\ub85c \uac31\uc2e0\ud574\ub77c\n<\/code><\/pre>\n<p><\/MdxAccordion><\/p>\n<h2>9. \uc870\uac74 \ubc14\uafb8\uae30<\/h2>\n<p>\uc218\uc9d1 \uc870\uac74\uc744 \ubc14\uafb8\uace0 \uc2f6\uc73c\uba74 AI\uc5d0\uac8c \uac04\ub2e8\ud788 \uc694\uccad\ud558\uba74 \ub41c\ub2e4.<\/p>\n<p><MdxNotice type=\"note\" title=\"\ub2e4\ub978 \uc9c1\ubb34\ub85c \ubc14\uafb8\uae30\"><\/p>\n<pre><code class=\"language-text\">\ud604\uc7ac \ucf54\ub4dc\ub294 \uc6f9\ub514\uc790\uc774\ub108 \ub300\uc0c1\uc774\ub2e4.\n\uc9c1\ubb34\ub97c \ud504\ub860\ud2b8\uc5d4\ub4dc\uac1c\ubc1c\uc790(\uc7a1\ucf54\ub9ac\uc544 1000230, \uc0ac\ub78c\uc778 92)\ub85c \ubc14\uafd4\ub77c.\n<\/code><\/pre>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"\uacbd\ub825 \uc870\uac74 \ubcc0\uacbd\"><\/p>\n<pre><code class=\"language-text\">\uc2e0\uc785\uc774 \uc544\ub2c8\ub77c \uacbd\ub825 3~5\ub144\uc73c\ub85c \ubc14\uafd4\ub77c.\n- \uc7a1\ucf54\ub9ac\uc544: careerType=2, careerMin=3, careerMax=5\n- \uc0ac\ub78c\uc778:   exp_cd=2 (+ \uacbd\ub825\uc5f0\ucc28 \ud30c\ub77c\ubbf8\ud130 \ud655\uc778)\n<\/code><\/pre>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"\uc9c0\uc5ed \ubcc0\uacbd\"><\/p>\n<pre><code class=\"language-text\">\uc11c\uc6b8\uc774 \uc544\ub2c8\ub77c \uacbd\uae30\ub3c4\ub85c \ubc14\uafd4\ub77c.\n- \uc7a1\ucf54\ub9ac\uc544: local \ud30c\ub77c\ubbf8\ud130\ub85c \uacbd\uae30\ub3c4 \ucf54\ub4dc \ucc3e\uc544\ub77c\n- \uc0ac\ub78c\uc778:   loc_mcd \uacbd\uae30\ub3c4 \ucf54\ub4dc\ub85c \ubc14\uafd4\ub77c\n<\/code><\/pre>\n<p><\/MdxNotice><MdxNotice type=\"note\" title=\"\uc9c1\uc6d0\uc218 \uc870\uac74\"><\/p>\n<pre><code class=\"language-text\">\uc9c1\uc6d0\uc218 \ud544\ud130\ub97c 10\uba85 \uc774\uc0c1\uc5d0\uc11c 50\uba85 \uc774\uc0c1\uc73c\ub85c \ubc14\uafd4\ub77c.\nCONFIG \ub515\uc154\ub108\ub9ac\uc758 min_employees \uac12\ub9cc \uace0\uce58\uba74 \ub418\ub294 \uad6c\uc870\uc5ec\uc57c \ud55c\ub2e4.\n<\/code><\/pre>\n<p><\/MdxNotice><\/p>\n<h2>10. \ubcf4\uc548\u00b7\uc724\ub9ac<\/h2>\n<p>\ud06c\ub864\ub9c1\uc740 \uc0c1\ub300 \uc11c\ubc84\uc5d0 \ubd80\ub2f4\uc744 \uc8fc\ub294 \ud589\uc704\ub2e4. \uc544\ub798 \uc6d0\uce59\uc744 \uc9c0\ud0a8\ub2e4.<\/p>\n<ul>\n<li><code>robots.txt<\/code> \ub97c \ud655\uc778\ud558\uace0 \ud5c8\uc6a9 \ubc94\uc704\ub97c \uc9c0\ud0a8\ub2e4<\/li>\n<li>\uc0ac\uc774\ud2b8 \uc774\uc6a9\uc57d\uad00\uc758 \ud06c\ub864\ub9c1 \uc870\ud56d\uc744 \uc900\uc218\ud55c\ub2e4<\/li>\n<li>\uc218\uc9d1\ud55c \ub370\uc774\ud130\ub97c \uc7ac\ubc30\ud3ec\ud558\uc9c0 \uc54a\ub294\ub2e4<\/li>\n<li>\uc694\uccad \uac04\uaca9\uc744 \ub450\uace0 \uc11c\ubc84 \ubd80\ub2f4\uc744 \ucd5c\uc18c\ud654\ud55c\ub2e4<\/li>\n<li>\uac1c\uc778\uc815\ubcf4(\uc774\uba54\uc77c\u00b7\uc804\ud654\ubc88\ud638)\ub294 \uc218\uc9d1\u00b7\uc800\uc7a5\ud558\uc9c0 \uc54a\ub294\ub2e4<\/li>\n<li>\uc0c1\uc5c5\uc801 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4<\/li>\n<\/ul>\n<h2>11. \ucc38\uace0 \uc790\ub8cc<\/h2>\n<ul>\n<li><a href=\"https:\/\/github.com\/google-gemini\/gemini-cli\">Gemini CLI \uacf5\uc2dd<\/a><\/li>\n<li><a href=\"https:\/\/claude.ai\">Claude<\/a><\/li>\n<li><a href=\"https:\/\/www.python.org\/downloads\/\">Python \uacf5\uc2dd \ub2e4\uc6b4\ub85c\ub4dc<\/a><\/li>\n<li><a href=\"https:\/\/docs.python.org\/ko\/3\/library\/venv.html\">\uac00\uc0c1\ud658\uacbd \uacf5\uc2dd \ubb38\uc11c<\/a><\/li>\n<li><a href=\"https:\/\/requests.readthedocs.io\/\">requests \uacf5\uc2dd \ubb38\uc11c<\/a><\/li>\n<li><a href=\"https:\/\/www.crummy.com\/software\/BeautifulSoup\/bs4\/doc\/\">BeautifulSoup \uacf5\uc2dd \ubb38\uc11c<\/a><\/li>\n<li><a href=\"https:\/\/openpyxl.readthedocs.io\/\">openpyxl \uacf5\uc2dd \ubb38\uc11c<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Claude\ub098 Gemini \uac19\uc740 AI\uc5d0\uac8c \uc2dc\ucf1c\uc11c \uc7a1\ucf54\ub9ac\uc544\u00b7\uc0ac\ub78c\uc778 \ucc44\uc6a9\uacf5\uace0 \ud06c\ub864\ub7ec\ub97c \uc9c1\uc811 \uc2e4\ud589\ud574 \ubcf8\ub2e4. \ud30c\uc774\uc36c\uc744 \ud55c \uc904\ub3c4 \uc368 \ubcf8 \uc801\uc774 \uc5c6\uc5b4\ub3c4 \ud504\ub86c\ud504\ud2b8\ub9cc \uc798 \uc8fc\uba74 \uc644\uc131\ub41c Excel \ud30c\uc77c\uc744 \ubc1b\uc744 \uc218 \uc788\ub2e4. 1. \uc900\ube44\ubb3c \ud56d\ubaa9 \uc124\uba85 \ucef4\ud4e8\ud130 \ub9e5\u00b7\uc708\ub3c4\uc6b0\u00b7\ub9ac\ub205\uc2a4 \ubaa8\ub450 \uac00\ub2a5 Python 3.10+ python.org\uc5d0\uc11c \uc124\uce58 AI \ub3c4\uad6c Claude \ub610\ub294 Gemini CLI VS Code code.visualstudio.com (\uc120\ud0dd) 2. \ud30c\uc774\uc36c &quot;\uac00\uc0c1\ud658\uacbd&quot; \ub9cc\ub4e4\uae30 \ud504\ub85c\uc81d\ud2b8\ub9c8\ub2e4 \ub3c5\ub9bd\ub41c &#8230; <a title=\"\uad6c\uc778\uc5c5\uccb4 \ub370\uc774\ud130 \uc218\uc9d1 \ud06c\ub864\ub7ec \ub9cc\ub4e4\uae30 (\ubc14\uc774\ube0c \ucf54\ub529)\" class=\"read-more\" href=\"https:\/\/coalacoding.com\/?p=1913\" aria-label=\"\uad6c\uc778\uc5c5\uccb4 \ub370\uc774\ud130 \uc218\uc9d1 \ud06c\ub864\ub7ec \ub9cc\ub4e4\uae30 (\ubc14\uc774\ube0c \ucf54\ub529)\uc5d0 \ub300\ud574 \ub354 \uc790\uc138\ud788 \uc54c\uc544\ubcf4\uc138\uc694\">\ub354 \uc77d\uae30<\/a><\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[],"class_list":["post-1913","post","type-post","status-publish","format-standard","hentry","category-backend-python-projects"],"_links":{"self":[{"href":"https:\/\/coalacoding.com\/index.php?rest_route=\/wp\/v2\/posts\/1913","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coalacoding.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coalacoding.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/coalacoding.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1913"}],"version-history":[{"count":1,"href":"https:\/\/coalacoding.com\/index.php?rest_route=\/wp\/v2\/posts\/1913\/revisions"}],"predecessor-version":[{"id":2182,"href":"https:\/\/coalacoding.com\/index.php?rest_route=\/wp\/v2\/posts\/1913\/revisions\/2182"}],"wp:attachment":[{"href":"https:\/\/coalacoding.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coalacoding.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coalacoding.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}