{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Menu List Crawling**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **1 청심중고교 메뉴 데이터 호출**\n", "무영 메뉴작업 목록 호출하기\n", "```python\n", "from muyong.food import menu_chungsim\n", "from tqdm import tqdm\n", "date = [str(_).split(\" \")[0][:-3] for _ in pd.date_range(start='1/1/2017', end=\"8/1/2019\", freq='MS')]\n", "result = [menu_chungsim(_).values.tolist() for _ in tqdm(date)]\n", "temp = []\n", "for _ in result:\n", " temp.extend(_)\n", "temp = pd.DataFrame(temp, columns = [\"Date\", \"조식\", \"중식\", \"석식\"])\n", "```" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Date조식중식석식
02017-01-01찰현미밥.떡만두국.진미채무침.계란찜.롤케익.골드파인애플/초코첵스하이라이스..돈목살스테이크/소스.치즈스틱/케찹.양송이버섯볶음.포기김치.이오 大찹쌀밥.된장찌개.한우버섯불고기.깐쇼새우.꽃상추무침.포기김치.쁘띠첼(90g)(핫도그....
12017-01-02찹쌀현미밥.돈육김치찌개.베이컨스크램블.코다리조림.부시맨빵/버터.후르트링/밀감혼합잡곡밥.사골우거지국.후라이드치킨/허니머스터드.꽈리고추메추리알조림.비타민무침.깍두...보리밥.맑은콩나물국.한우갈비찜.팔보채.오이양파무침.포기김치.장프로바이오틱(주먹밥.카...
\n", "
" ], "text/plain": [ " Date 조식 \\\n", "0 2017-01-01 찰현미밥.떡만두국.진미채무침.계란찜.롤케익.골드파인애플/초코첵스 \n", "1 2017-01-02 찹쌀현미밥.돈육김치찌개.베이컨스크램블.코다리조림.부시맨빵/버터.후르트링/밀감 \n", "\n", " 중식 \\\n", "0 하이라이스..돈목살스테이크/소스.치즈스틱/케찹.양송이버섯볶음.포기김치.이오 大 \n", "1 혼합잡곡밥.사골우거지국.후라이드치킨/허니머스터드.꽈리고추메추리알조림.비타민무침.깍두... \n", "\n", " 석식 \n", "0 찹쌀밥.된장찌개.한우버섯불고기.깐쇼새우.꽃상추무침.포기김치.쁘띠첼(90g)(핫도그.... \n", "1 보리밥.맑은콩나물국.한우갈비찜.팔보채.오이양파무침.포기김치.장프로바이오틱(주먹밥.카... " ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2017-01-01 부터 수집 가능합니다.\n", "import pandas as pd\n", "df = pd.read_csv('data/menu_chungsim.csv')\n", "df.head(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 성균관 대학교 메뉴 데이터 호출**\n", "무영 메뉴작업 목록 호출하기 : 1년 전까지만 호출가능\n", "```python\n", "div class=\"weekly_list\"\n", "div class=\"tabCon listcon1\"\n", "div class=\"weeListWrap\" # div class=\"weeListTit\" : 날짜만 추출시\n", "idx_date_range = [_.date().strftime(\"%Y-%m-%d\") \n", " for _ in pd.date_range(start=idx_date, periods=len(menu_detail))]\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "# **10,000 개의 레시피 메뉴 함수**\n", "개별 작업을 구분한 뒤, 모듈로써 작업을 진행하도록 합니다\n", "1. **크롤링용** 함수\n", "1. 원본과 **비교용** 함수\n", "1. **비교 후 합치는** 함수\n", "\n", "## **1 작업용 함수 만들기**\n", "크롤링 및 주소값을 활요한 filtering" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[['/recipe/6917104', '콩국수 ~#'],\n", " ['/recipe/6917103', '5분이면 가능한 \"건새우 볶음\"'],\n", " ['/recipe/6917102', '간단 참치전~*']]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# \"<제목>\" 추출시 lxml 로는 안되더라 왜????\n", "import requests, re\n", "from bs4 import BeautifulSoup\n", "def crawMenuBs4(url_no):\n", " url = \"http://www.10000recipe.com/recipe/list.html?order=date&page=\"\n", " userAgent = {\"user-agent\":\"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0\"}\n", " result, resp = [], requests.request('get', url+str(url_no), headers=userAgent, timeout=5)\n", " dom = BeautifulSoup(resp.text, \"html.parser\") \n", " titles = dom.find_all(\"h4\", {\"class\":\"ellipsis_title2\"})\n", " titles = [_.text for _ in titles]\n", " for _ in dom.find_all(\"div\", {\"class\":\"col-xs-4\"}):\n", " try:\n", " url_href = _.find(\"a\", {\"class\":\"thumbnail\"})[\"href\"]\n", " _title = _.find(\"h4\", {\"class\":\"ellipsis_title2\"}).text\n", " result.append([url_href, _title])\n", " except: pass\n", " return result\n", " \n", "# 특정 페이지 링크데이터 목록 수집하기\n", "menuList = crawMenuBs4(17)\n", "menuList[:3]" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# 파일을 기준으로 결과물 필터링\n", "import pandas as pd\n", "def crawFileFilter(menuList, files):\n", " df = pd.read_csv(files, header=None)\n", " limitOrg = int(re.findall(r\"\\d+\", df[0][0])[0])\n", " mTemp = pd.DataFrame(menuList)\n", " mTemp[0] = [int(re.findall(r\"\\d+\", _)[0]) for _ in mTemp[0]]\n", " mTemp = mTemp[mTemp[0] > limitOrg]\n", " mTemp[0] = [\"/recipe/\"+str(_) for _ in mTemp[0]] # 필터링 결과 url\n", " return mTemp.values.tolist()" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [], "source": [ "# Web Page 수집함수\n", "import requests\n", "from lxml.html import fromstring\n", "def crawData(url_menu):\n", " url = \"http://www.10000recipe.com/recipe/list.html?order=accuracy&page=\"\n", " url = \"http://www.10000recipe.com/recipe/\"\n", " userAgent = {\"user-agent\":\"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0\"}\n", " xpath_rcp = '//div[@id=\"contents_area\"]//div[starts-with(@class,\"cont_ingre\")]//text()'\n", " xpath_c = '//div[@id=\"contents_area\"]/div[@class=\"view_step\"]/div[starts-with(@id,\"stepDiv\")]//text()'\n", " xpath_cOld = '//div[@id=\"contents_area\"]/div[@class=\"view_step\"]/div[@id=\"oldContArea\"]//text()'\n", " xpath_tip = '//div[@id=\"contents_area\"]/div[@class=\"view_step\"]//dl[@class=\"view_step_tip\"]//text()'\n", " xpath_name = '//div[@id=\"contents_area\"]/div[@class=\"view2_summary\"]/h3/text()'\n", " urlDetail = requests.compat.urljoin(url, url_menu)\n", " # urlDetail = url + str(url_menu)\n", " resp = requests.request('get', urlDetail, headers=userAgent, timeout=5)\n", " resp_lxml = fromstring(resp.text)\n", " try:\n", " name = resp_lxml.xpath(xpath_name) # 레시피 데이터\n", " name = \" \".join([_.strip() for _ in name if len(_.strip())>1])\n", " recipe = resp_lxml.xpath(xpath_rcp) # 레시피 데이터\n", " recipe = \" \".join([_.strip() for _ in recipe if len(_.strip())>1])\n", " cooking = resp_lxml.xpath(xpath_c) # 조리법 크롤링\n", " cooking = \" \".join([_.strip() for _ in cooking if len(_.strip())>1])\n", " if len(cooking) < 5: # 조리법 크롤링 (old style)\n", " cooking = resp_lxml.xpath(xpath_cOld)\n", " cooking = \" \".join([_.strip() for _ in cooking if len(_.strip())>1])\n", " cookTip = resp_lxml.xpath(xpath_tip)\n", " cookTip = \" \".join([_.strip() for _ in cookTip if len(_.strip())>1])\n", " if len(cookTip) < 3: cookTip=\"None\"\n", " # url 은 레시피 Url 숫자 저장 (압축)\n", " url_menu = int(\"\".join(re.findall(r'\\d+', url_menu)))\n", " return [url_menu, name, recipe, cooking, cookTip]\n", " except: return None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 레시피 데이터 전처리**\n", "작업한 내용 살펴보기" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# import pandas as pd\n", "# recipes = pd.read_csv('data/foodRecipe.csv', sep=\"|\", header=None)\n", "# recipes[0] = [int(_) for _ in recipes[0]] # 문자열 대신 숫자로 모두 변환\n", "\n", "# # 중복 컬럼 줄이기 : 6917054, 6917053, 6917052, 6917051, 6917050, 6917049\n", "# from tqdm import tqdm\n", "# result, recipesNo = [], sorted(set(recipes[0]), reverse=True)\n", "# for _ in tqdm(recipesNo):\n", "# result.append(recipes[recipes[0] == _].iloc[0,:].values.tolist())\n", "# recipes = pd.DataFrame(result)\n", "# recipes.to_csv('recipe.csv', index=None, header=None, sep=\"|\")\n", "# recipes.head(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "# **Naver 자료 수집하기**\n", "Naver 자료들 수집하기\n", "\n", "## **1 네이버 블로그 내용 수집하기**\n", "블로그 URL 에서 본문을 수집 분석하기" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'요리하다 [김치만두전골 황금레시피]알배추를 넣어 얼큰한 겨울국물요리 캐리정 ・ 2018. 12. 3. 21:30 URL 복사 이웃추가 본문 기타 기능 번역보기 얼큰한 겨울 국물요리 김치만두전골 황금레시피 으슬으슬 추 운 계절에는 얼큰 시원한 국물요리만한게 없죠 여기에 든든한 만두가 가세한 만두 전골냄비 한 그릇만으로 다른 반찬 필요없어용~ 김치만두전골 황금레시피 컨셉: 든든한 국물요리 ** 만두전골 재료 2인분\\xa0** 직접 만든 김치손만두 4개 '" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# iframe 으로 본문 url 찾은 뒤, //div[@id=\"postListBody\"] 내용의 출력\n", "import requests\n", "from lxml.html import fromstring\n", "\n", "def get_blog_post(url):\n", " userAgent = {\"user-agent\":\"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0\"}\n", " rsp = requests.get(url, headers=userAgent)\n", " rsp_lxml = fromstring(rsp.text) # './/태그[contains(@속성명, \"속성값\")]'\n", " text_result = rsp_lxml.xpath('.//iframe[@id=\"mainFrame\"]/@src')\n", " get_url = \"https://blog.naver.com\" + text_result[0]\n", " resp = requests.get(get_url)\n", " resp_lxml = fromstring(resp.text)\n", " blog_xpath = '//div[@id=\"postListBody\"]//table//text()'\n", " return \" \".join([_.strip() for _ in resp_lxml.xpath(blog_xpath) if _.strip()])\n", "\n", "url = \"https://blog.naver.com/k77609/221366368354\"\n", "url = 'https://blog.naver.com/0167513714/221616708943'\n", "url = 'https://blog.naver.com/hnn888/221411518781'\n", "blog_text = get_blog_post(url)\n", "blog_text[:250]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from konlpy.tag import Mecab, Okt\n", "blog_text\n", "tokens = [_[0]+\"/\"+_[1] for _ in Mecab().pos(blog_text)] # , stem=True\n", "\n", "from nltk import Text\n", "token_blog = Text(tokens) # [list] 객체로 Text 객체의 생성" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3IAAAECCAYAAAC7auUJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd7wcVf3/8dfn5qYTQklCQktCk95uaEloGgVFIGIBEUUFI1LUn34FCwjKV/mCCiJNAQUFLKgBCQLSW0KAG4oghBIIECAhBFJIL5/fH2eWbK53d2fn7O7ce/N+Ph77uHfLZz5nZ2fOzJmZc8bcHREREREREek8mvIugIiIiIiIiFRHDTkREREREZFORg05ERERERGRTkYNORERERERkU5GDTkREREREZFORg05ERERERGRTqY57wKUMmDAAB82bFjexfgvixcvpnfv3rnEK/falTs2XrmVW7m7bu7YeOVWbuXuurlj45W7Y5kyZcrb7j6w3TfdvUM+WlpavCNqbW3NLV65167csfHKrdzK3XVzx8Yrt3Ird9fNHRuv3B0L0Ool2ku6tFJERERERKSTUUNORERERESkk1FDTkREREREpJNRQ05ERERERKST6bCjVnZEJ//xMR6ZNpued92dKd4w9t+kiZaWGhdMRERERETWKmrIVeGtBUt5a+FKWLg48zSuewc+M2MeO23av4YlExERERGRtYkaclW46LO70fr4k+y0406Z4n/74Ev8/qFX+N4N/+bGE0fR3E1XtoqIiIiISPXUkKvCRuv2YvA6zWy+YZ9M8acevC3/fPI1nn59PldPms7x+25R4xKKiIiIiMjaQKeEGqhvz2bG7b4uAOff8Tyvz81+iaaIiIiIiKy91JBrsJYhvThkpyEsWraSH974NOGG7SIiIiIiIumpIZeDMw/dnn69mrlr6lvc+vTMvIsjIiIiIiKdjBpyORi0bi9OO3hbAM666T/MX7I85xKJiIiIiEhnooZcTo7ec3N233w93lqwlPNum5p3cUREREREpBNRQy4nTU3GOUfsTHOTcd3DrzLllXfzLpKIiIiIiHQSdW3ImdkoM3vdzI4qeu0jZqYRPoAPDO7HuP22wB2+P/4plq9clXeRRERERESkE6hbQ87MNgXOBv7V5q1TgTfrlbez+fqHtmbohn14btYC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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "from matplotlib import rc, rcParams\n", "import matplotlib.pyplot as plt\n", "rc('font', family=['UbuntuMono-R', 'D2Coding']) # 한글의 표시\n", "rcParams['axes.unicode_minus'] = False # '-' 표시의 처리\n", "plt.figure(figsize=(15, 3)) # 파레트 설정\n", "token_blog.plot(50)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# **Naver Post Detail Crawling**\n", "메뉴의 이름들 중 대표성 높은 메뉴들 찾기\n", "\n", "## **1 네이버 블로그 내용 수집하기**\n", "블로그 URL 에서 본문을 수집 분석하기\n", "1. Naver OPEN API 결과 **Token 이 유효값인지** 확인 가능했다 (Oh!!)\n", "1. 네이버 블로그 목록만 정리한 DataBase 만들기\n", "1. 목록을 4개로 나워서 2개의 서버에서 돌리며 저장하기" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import re\n", "# 수집결과 불필요한 기호들 제거하는 함수\n", "def blog_preprocess(post):\n", " post_temp = post.replace('\\n',\"\").replace('\\t',\"\").split(\".\")\n", " post_temp = [\" \".join(re.findall(r\"[가-힣0-9A-z]+\", _)) for _ in post_temp if len(_.strip()) >= 1]\n", " return \".\".join(post_temp)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# import pandas as pd\n", "# links_org = pd.read_csv('backup/naver_link_temp.csv')\n", "# # links_org.shape, links_org.head(3)\n", "# links_by_token = links_org.iloc[::60, :] # 길이를 절반으로 축소\n", "# links_by_token = links_by_token.data.values.tolist()\n", "# len(links_by_token), links_by_token[0][:40]" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# import sqlite3, time, os, requests_cache\n", "# file_db = \"naver.db\"\n", "# conn = sqlite3.connect(file_db)\n", "# requests_cache.install_cache('cache')\n", "\n", "# import pandas as pd\n", "# from tqdm import tqdm\n", "# from muyong.util import Telegram\n", "# from muyong.naver import get_blog_post\n", "# t = Telegram()\n", "# links_length = len(links_by_token)\n", "# for no, links in tqdm(enumerate(links_by_token)):\n", "# result, temp = [], []\n", "# links = links.split('|')\n", "# for _ in links[:100]:\n", "# _ = get_blog_post(_)\n", "# _ = blog_preprocess(_)\n", "# temp.append(_)\n", "# time.sleep(.1)\n", "# temp = \"|\".join(temp) # 500개를 저장\n", "# result.append([no, temp])\n", "# df = pd.DataFrame(result)\n", "# df.to_sql('foods', conn, if_exists='append')\n", "# os.remove(\"cache.sqlite\")\n", "# if no % 200 == 0:\n", "# t.msg(\"{}/ {} th processing\".format(no, links_length))\n", "# time.sleep(.1)\n", "# conn.commit()\n", "# conn.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## **2 수집결과 살펴보기**\n", "Sqlite 결과를 보다 활용하기 쉽게 저장하기" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# import sqlite3\n", "# import pandas as pd\n", "# conn = sqlite3.connect(\"naver.db\")\n", "# df = pd.read_sql('SELECT * FROM \"foods\"', conn, index_col=None).drop('index', axis=1)\n", "# conn.close()\n", "# df = df.iloc[11:].reset_index(drop=True)\n", "# df.columns = ['Query', 'Posts']\n", "# df.Query = links_org.iloc[::60, 0].tolist()\n", "# df.head()\n", "\n", "# df.to_csv(\"data/naver_posts_sample.csv\", index=None)\n", "# df.Query.tolist()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 4 }