๐Ÿค–[์›น์†Œ์„ค] ์ผํƒ€๊ฐ•์‚ฌ AI์˜ ๊ธฐ๋ง‰ํžŒ ์ถ”์ฒœ

logo

[์›น์†Œ์„ค] ์ผํƒ€๊ฐ•์‚ฌ AI์˜ ๊ธฐ๋ง‰ํžŒ ์ถ”์ฒœ

๋จธ์‹ ๋Ÿฌ๋‹ ์ถ”์ฒœ ์‹œ์Šคํ…œ ํ”„๋กœ์ ํŠธ

๋„ค์ด๋ฒ„ ์‹œ๋ฆฌ์ฆˆ์—์„œ ํŒ๋งค์ค‘์ธ ์›น์†Œ์„ค ์ž‘ํ’ˆ์˜ ์ž‘ํ’ˆ์ •๋ณด๋ฅผ ํฌ๋กค๋งํ•˜์—ฌ ์–ป์€ ์ค„๊ฑฐ๋ฆฌ๋ฅผ ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์—ฌ ์›น์†Œ์„ค์˜ ์Šคํ† ๋ฆฌ๋ฅผ ๋ฒกํ„ฐ ์ž„๋ฒ ๋”ฉ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํ˜ธํ•œ ์†Œ์„ค์˜ ์ค„๊ฑฐ๋ฆฌ์™€ ์œ ์‚ฌ๋„๊ฐ€ ๋†’์€ ์ž‘ํ’ˆ์„ ์ถ”์ฒœํ•ด์ฃผ๋Š” ์„œ๋น„์Šค


ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋‚˜์˜ ์—ญํ•  โ†’ โ€œ๋ณด๋Ÿฌ๊ฐ€๊ธฐ๐Ÿ‘€โ€


๐Ÿ”—์‹œ์—ฐ์˜์ƒ


image image image image
๋กœ๊ทธ์ธ ํšŒ์›๊ฐ€์ž… ๋ฉ”์ธ ํŽ˜์ด์ง€ ์žฅ๋ฅด๋ณ„ ์ž‘ํ’ˆ ๋ฆฌ์ŠคํŠธ
image image image image
๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์ž‘ํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€ ๋งˆ์ด ํŽ˜์ด์ง€ ๋‚˜์˜ ๋ฆฌ๋ทฐ ๋ชจ์•„๋ณด๊ธฐ


ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„

2022-06-02 ~ 2022-06-13


์ฃผ์š” ๊ธฐ๋Šฅ

  1. Django ๋‚ด์žฅ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•œ ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ
  2. ๋„ค์ด๋ฒ„ ์‹œ๋ฆฌ์ฆˆ์—์„œ ํŒ๋งค์ค‘์ธ ์›น์†Œ์„ค ์ž‘ํ’ˆ์˜ ์ž‘ํ’ˆ์ •๋ณด๋ฅผ BeautifulSoup๊ณผ Selenium์„ ์ด์šฉํ•˜์—ฌ ํฌ๋กค๋ง
  3. ์ž์—ฐ์–ด ์ฒ˜๋ฆฌ๋ฅผ ์ด์šฉํ•ด ์›น์†Œ์„ค์˜ ์Šคํ† ๋ฆฌ๋ฅผ ๋ฒกํ„ฐ ์ž„๋ฒ ๋”ฉ
  4. ์‚ฌ์šฉ์ž๊ฐ€ ์ข‹์•„ํ•œ ์ž‘ํ’ˆ์˜ ์ค„๊ฑฐ๋ฆฌ์™€ ์œ ์‚ฌ๋„๊ฐ€ ๋†’์€ ์ž‘ํ’ˆ์„ ์ถ”์ฒœ
    • ๋“ฑ๋ก๋œ ์„ ํ˜ธ์ž‘์ด ์—†๋‹ค๋ฉด ๋ณ„์ ์ด ๋†’์€ ์ž‘ํ’ˆ๋“ค์„ ์ถ”์ฒœ
  5. ์ž‘ํ’ˆ์— ๋Œ€ํ•œ ๋ฆฌ๋ทฐ CRUD ๊ธฐ๋Šฅ
  6. ๋ฆฌ๋ทฐ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ๊ฐ€์žฅ ๋งŽ์€ ํ‚ค์›Œ๋“œ 5๊ฐœ ํ‘œ์‹œ (์ž‘ํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€)
  7. ์ข‹์•„ํ•œ ์ž‘ํ’ˆ์˜ ์Šคํ† ๋ฆฌ ํ‚ค์›Œ๋“œ ๋นˆ๋„์ˆ˜ ์ƒ์œ„ 10๊ฐœ ํ‘œ์‹œ (๋งˆ์ด ํŽ˜์ด์ง€)


ํ”„๋กœ์ ํŠธ ๊ธฐ๋ก

๐Ÿ”—Github
๐Ÿ”—Starting Assignment (tistory)


ํŒ€ ๊ตฌ์„ฑ ๋ฐ ์—ญํ• 

์ด๋ฆ„ ์—ญํ•  ๊นƒํ—ˆ๋ธŒ
์ด์ •์•„ย ย ย ย  ์‹œ๋ฏผ์ฆ ๋ฐœ๊ธ‰ ํŽ˜์ด์ง€, ์ƒ์  ํŽ˜์ด์ง€(back), ๋ฐฉ ๊พธ๋ฏธ๊ธฐ ๊ธฐ๋Šฅ, ๋”ฅ๋Ÿฌ๋‹ย ย ย ย  ๐Ÿ”—zeonga1102
๋…ธ์„ ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€, ์ƒ์  ํŽ˜์ด์ง€(front), ๋กœ๊ณ  ์ œ์ž‘ ๐Ÿ”—minkkky
์ดํ˜„๊ฒฝ ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€, AWS ๋ฐฐํฌ ๐Ÿ”—LULULALA2
๊น€๋™๊ทผ ๋งˆ์ด ํŽ˜์ด์ง€ ๐Ÿ”—yinmsk


์Šคํ‚ฌ ๋ฐ ์‚ฌ์šฉํˆด

Python, Django, BeautifulSoup, Selenium, Colab, MeCab, Doc2Vec

DB(ERD)

image



ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋‚˜์˜ ์—ญํ•  ๋ฐ ๊ฒฝํ—˜

๋‚˜์˜ ์—ญํ• 


1. ๋ฉ”์ธํŽ˜์ด์ง€ Today best top 20 ํฌ๋กค๋ง

import requests
from bs4 import BeautifulSoup

url = 'https://series.naver.com/novel/top100List.series?rankingTypeCode=DAILY&categoryCode=ALL'

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url,headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')

lis = soup.select('#content > div > ul > li')

li_list = []

for li in lis:
    cover_line = li.select_one('a > img')
    cover = cover_line['src']
    title = cover_line['alt']
    author = li.select_one('div.comic_cont > p.info > span:nth-child(4)').text
    star = li.select_one('div.comic_cont > p.info > em.score_num').text
    detail = li.select_one('div.comic_cont > p.info > span:nth-child(6)').text

    dic = {'cover':cover, 'title':title, 'author':author, 'author':author, 'star':star, 'detail':detail}

    li_list.append(dic)

print(li_list)



๐ŸงจTroubleShooting

1. ํฌ๋กค๋งํ•  ํŽ˜์ด์ง€๊ฐ€ ๋™์ ํŽ˜์ด์ง€์—ฌ์„œ BeautifulSoup ์‚ฌ์šฉ ๋ถˆ๊ฐ€

์ฒ˜์Œ์— ํฌ๋กค๋ง์„ ํ•  ๋•Œ bs4๋ฅผ ์ด์šฉํ•ด ์ „์ฒด ์ž‘ํ’ˆ๋ชฉ๋ก์—์„œ ๊ฐ ์ž‘ํ’ˆ์˜ ์ƒ์„ธํŽ˜์ด์ง€๋กœ ์—ฐ๊ฒฐ๋˜๋Š” url์„ ํฌ๋กค๋งํ•˜๊ณ , ํฌ๋กค๋งํ•œ url์— ๊ฐ๊ฐ ์ ‘์†ํ•˜์—ฌ ์ž‘ํ’ˆ๋“ค์˜ ์ƒ์„ธ์ •๋ณด๋ฅผ ํฌ๋กค๋งํ•ด์™”๋‹ค. ๊ฐ ์ž‘ํ’ˆ ์ƒ์„ธํŽ˜์ด์ง€์—์„œ ์ž‘ํ’ˆ์˜ ์ „์ฒด ์ค„๊ฑฐ๋ฆฌ๋Š” <๋”๋ณด๊ธฐ> ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์•ผ๋งŒ ๋ณด์ด๋Š” ๋ฐฉ์‹์ด์–ด์„œ ํฌ๋กค๋ง ๊ฒฐ๊ณผ๋ฌผ์— ์ž‘ํ’ˆ์ค„๊ฑฐ๋ฆฌ๊ฐ€ ์ „๋ถ€ ์ž˜๋ ค์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋™์ ํŽ˜์ด์ง€์—์„œ๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ selenium ์„ ๊ฐ™์ด ์‚ฌ์šฉํ–ˆ๋‹ค.

(์ฝ”๋žฉ : https://colab.research.google.com/drive/1olprD0sgSfZdq36o8ox0_lx8DLN1f7US?usp=sharing)


2. ๋ฆฌ๋ทฐ ์ˆ˜์ • ํ›„ ์ €์žฅ์„ ๋ˆ„๋ฅด๋ฉด โ€˜ReviewModelโ€™ object has no attribute โ€˜updateโ€™ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๋ฌธ์ œ

์˜ค๋ฅ˜๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๊ณ  ์ฒ˜์Œ์— update ํ•จ์ˆ˜์—์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ์ค„ ์•Œ์•˜๋Š”๋ฐ, origin_review ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋Œ€์ƒ์ด ์ž˜๋ชป๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜๋‹ค. get() ์ด ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ํ•˜๋‚˜์ด๊ณ , filter()๋Š” ํ•ด๋‹นํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ํฌํ•จํ•˜๋Š” QuerySet์„ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์–ด์„œ origin_review ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ReviewModel.objects.get(id=review_id) ๋ฅผ ReviewModel.objects.filter(id=review_id) ๋กœ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

# modify_review
@login_required
def modify_review(request, book_id, review_id):
    origin_review = ReviewModel.objects.filter(id=review_id)

    if request.method == "POST":
        star = int(request.POST.get('rating', 0))
        review = request.POST.get('review', '')
        date = timezone.now()

        origin_review.update(star=star, desc=review, date=date)

        return redirect('book_info', book_id)



ํšŒ๊ณ 

ํฌ๋กค๋ง์„ ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ์‹œ๊ฐ„์„ ์žก์•„๋จน์—ˆ๋‹ค. ๊น”๋”ํ•˜๊ฒŒ ํฌ๋กค๋ง์„ ํ•˜๊ธฐ์œ„ํ•ด ๊ณ ๋ คํ•ด์•ผํ•  ๊ฒƒ๋„ ๋งŽ์•˜๊ณ , ๊ทœ์น™์ ์ด์ง€ ์•Š์•„์„œ ํฌ๋กค๋ง์ด ๋ถˆ๊ฐ€๋Šฅ ํ•œ ๊ฒƒ๋„ ๋งŽ์•˜๋‹ค.์›๋ž˜ ์›นํƒ€์ถ”๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ๊ฒƒ์€ ์‚ฌ์šฉ์ž์˜ ํ‰์ ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์†Œ์„ค์„ ์ถ”์ฒœํ•ด์ฃผ๋Š” ํ˜‘์—…ํ•„ํ„ฐ๋ง ๋ฐฉ์‹์˜ ์ถ”์ฒœ์‹œ์Šคํ…œ์ด์—ˆ๋Š”๋ฐ, ์œ ์ €๋ฐ์ดํ„ฐ๊ฐ€ ์—†์–ด์„œ ์ค„๊ฑฐ๋ฆฌ๋ฅผ ๋ถ„์„ํ•ด์„œ ์œ ์‚ฌ๋„๊ฐ€ ๋†’์€ ์›น์†Œ์„ค์„ ์ถ”์ฒœํ•ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋…ธ์„ ์„ ๋ณ€๊ฒฝํ•ด์„œ ์กฐ๊ธˆ ์•„์‰ฌ์› ๋‹ค.

ํฌ๋กค๋งํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ชจ๋ธ์„ ํ…Œ์ŠคํŠธํ•ด๋ณธ ๊ฒฐ๊ณผ ์ค„๊ฑฐ๋ฆฌ๊ฐ€ ์œ ์‚ฌํ•œ ์ž‘ํ’ˆ์„ ์ž˜ ์ถ”์ฒœํ•˜๊ธฐ๋Š” ํ•˜์ง€๋งŒ, ์ค„๊ฑฐ๋ฆฌ๊ฐ€ ์†Œ์„ค์˜ ์ „์ฒด๋ฅผ ์ž˜ ๋ฐ˜์˜ํ•˜๊ธฐ๋Š” ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์ž‘ํ’ˆ ๋ถ„์œ„๊ธฐ๋‚˜ ๋ฌธ์ฒด ๋“ฑ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์—†์–ด์„œ ์‹ค์ œ ์„œ๋น„์Šค๋ฅผ ํ–ˆ์„ ๋•Œ ์‚ฌ์šฉ์ž์˜ ๋งŒ์กฑ๋„๊ฐ€ ๋†’์„ ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š์•˜๋‹ค.

ํ”„๋กœ์ ํŠธ ํ›„๋ฐ˜์—๋Š” ํ™”๋ฉด๊ณต์œ ๋ฅผ ํ•˜๋ฉด์„œ ์„ธ๋ถ€์ ์ธ ๋””์ž์ธ ๋ณ€๊ฒฝ์ด๋‚˜ ์ž์ž˜ํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฒ„๊ทธ๋ฅผ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋ฐœ๊ฒฌํ•˜๊ณ  ๋‚˜๋ˆ ์„œ ์ˆ˜์ •ํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ๋‹ค. ์ ์  ํŒ€์›Œํฌ๋„ ๋” ์ž˜ ๋งž๋Š” ๊ฒƒ ๊ฐ™๊ณ , ๋‹ค๋“ค ์—ด์ •์ ์ด๋ผ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋” ์žฌ๋ฏธ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.