Showing
5 changed files
with
64 additions
and
2 deletions
... | @@ -28,6 +28,8 @@ | ... | @@ -28,6 +28,8 @@ |
28 | ### 사용기술 | 28 | ### 사용기술 |
29 | * Nodejs | 29 | * Nodejs |
30 | * Express | 30 | * Express |
31 | +* web crawling | ||
32 | +* MySQL | ||
31 | 33 | ||
32 | --- | 34 | --- |
33 | ### 사용법 | 35 | ### 사용법 |
... | @@ -47,8 +49,8 @@ | ... | @@ -47,8 +49,8 @@ |
47 | --- | 49 | --- |
48 | ### 진행정도 | 50 | ### 진행정도 |
49 | - [x] 챗봇을 올릴 aws 서비스 생성 | 51 | - [x] 챗봇을 올릴 aws 서비스 생성 |
50 | -- [x] 식약처 레시피 open api 키 신청 | 52 | +- [x] 만개의 레시피 사이트에서 메뉴, 재료, 레시피 크롤링 |
51 | -- [ ] 코드 짜기 | 53 | +- [ ] 생성된 데이터베이스를 이용하는 코드 작성 |
52 | 54 | ||
53 | --- | 55 | --- |
54 | ### 만든사람 | 56 | ### 만든사람 | ... | ... |
images/Crawled_example.png
0 → 100644

289 KB
images/db_import1.PNG
0 → 100644
7.4 KB
images/db_import2.PNG
0 → 100644
15.8 KB
recipes/Crawling_Script.py
0 → 100644
1 | +import time | ||
2 | +import requests | ||
3 | +from bs4 import BeautifulSoup | ||
4 | +import pymysql | ||
5 | + | ||
6 | +#pip3 install requests, pip3 install pymyaql, pip3 install beautifulsoup4를 하고 진행, pip3대신 pip 사용가능 | ||
7 | +#사이트가 크롤링을 공격으로 인식하는 것을 방지하기 위해 중간중간에 sleep함수를 사용 | ||
8 | + | ||
9 | + | ||
10 | +conn = pymysql.connect(host="localhost", user="root",password='abcde12345abcde',db='db_recipe', charset='utf8') | ||
11 | +curs = conn.cursor(pymysql.cursors.DictCursor) | ||
12 | + | ||
13 | +for pagenum in range(1,35): #크롤링 할 상위 페이지 개수. 약 40개정도의 레시피 링크가 한 페이지에 이어져 있음 | ||
14 | + print(pagenum) | ||
15 | + page = requests.get('https://www.10000recipe.com/recipe/list.html?order=reco&page='+str(pagenum)) | ||
16 | + | ||
17 | + soup = BeautifulSoup(page.content, 'html.parser') | ||
18 | + anchors = soup.find_all("a", {"class": "common_sp_link"}) | ||
19 | + | ||
20 | + | ||
21 | + for anch in anchors: | ||
22 | + time.sleep(7) | ||
23 | + print(pagenum, anch.get('href')) | ||
24 | + page2 = requests.get('https://www.10000recipe.com' + anch.get('href')) | ||
25 | + soup2 = BeautifulSoup(page2.content, 'html.parser') | ||
26 | + | ||
27 | + #모든 레시피 형식이 같지 않아 에러 발생 가능성이 있음 | ||
28 | + res1 = soup2.find('div', 'view2_summary st3') | ||
29 | + if not res1: continue | ||
30 | + res1 = res1.find('h3') | ||
31 | + db_menu = res1.get_text() | ||
32 | + | ||
33 | + ingList = [] | ||
34 | + res2 = soup2.find('div', 'ready_ingre3') | ||
35 | + try: | ||
36 | + for ultag in res2.find_all('ul'): | ||
37 | + source = [] | ||
38 | + for litag in ultag.find_all('li'): | ||
39 | + tli = litag.get_text().replace(' ','').split('\n') | ||
40 | + ingList.append(tli[0]) | ||
41 | + db_ingr = ','.join(ingList) | ||
42 | + except(AttributeError): | ||
43 | + continue | ||
44 | + | ||
45 | + db_recipe = '' | ||
46 | + res3 = soup2.find('div', {"class": "view_step"}) | ||
47 | + res3 = res3.find_all('div') | ||
48 | + for stepdiv in res3: | ||
49 | + if not stepdiv.has_attr('class'): continue | ||
50 | + if 'view_step_cont' in stepdiv['class'][0]: | ||
51 | + if not 'media'==stepdiv['class'][1]: continue | ||
52 | + db_recipe += stepdiv.get_text() | ||
53 | + if len(db_recipe)<50: continue | ||
54 | + db_recipe = db_recipe[0:998] | ||
55 | + | ||
56 | + sql = 'INSERT INTO recipe(menu, ingrediant, recipe) VALUES (%s, %s, %s)' | ||
57 | + curs.execute(sql, (db_menu,db_ingr,db_recipe)) | ||
58 | + conn.commit() | ||
59 | + | ||
60 | +conn.close() |
-
Please register or login to post a comment