TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 데이터 분석>

[파이썬] 자연어 처리(NLP) - 여자친구 선물 고르기 : 1

by 기록자_Recordian 2024. 5. 15.
728x90
반응형
시작에 앞서
해당 내용은 <파이썬으로 데이터 주무르기> -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.
보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.

지난 챕터
 

[파이썬] 자연어 처리(NLP) 시작하기 - 8

시작에 앞서해당 내용은 -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.지난 챕터 [파이썬] 자연어 처리(NLP) 시작하기

puppy-foot-it.tistory.com


여자친구 선물 고르기

 

네이버의 지식인에서 여자친구 선물 이라는 주제로 검색을 하고 그 검색 결과를 자연어 처리

먼저 네이버 지식인에서 '여자 친구 선물' 검색 후, 크롬 개발자 도구(F12)로 질문에 대한 답변이 위치한 곳의 태그 찾음

지식인 답변 태그 확인
div 태그라는 것을 알 수 있다

 

그리고 그래프를 그리기 위한 코드와 웹 스크래핑을 위한 코드 입력

import pandas as pd
import numpy as np

import platform
import matplotlib.pyplot as plt

%matplotlib inline

#한글 폰트 문제 해결
path = "c:/Windows/Fonts/malgun.ttf"

from matplotlib import font_manager, rc
if platform.system() == 'Windows':
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Sorry')

# 마이너스 기호가 깨지는 문제를 해결
plt.rcParams['axes.unicode_minus'] = False

# 웹 스크래핑을 위한 BeautifulSoup와 urllib을 import 
from bs4 import BeautifulSoup
from urllib.request import urlopen
import urllib
import time

 

그다음, 주소 부분을 약간 편집하여 접근해야 할 주소를 정한다.

# 네이버 지식인 검색 페이지의 기본 URL이 할당
tmp1 = 'https://search.naver.com/search.naver?wher=kin'

# tmp1 변수와 추가적인 매개변수를 포함한 URL이 할당
html = tmp1 + '&sm=tab.jum&ie=utf8&query={key_word}&start={num}' # {key_word}: 검색어, {num}: 검색 결과의 시작 위치

#  html 변수에 저장된 URL에 검색어 '여친 선물'을 인코딩하여 포함시키고, 첫 번째 페이지의 검색 결과를 가져옴
response = urlopen(html.format(num=1, key_word=urllib.parse.quote('여친 선물')))

#가져온 HTML 문서를 BeautifulSoup을 사용하여 파싱
soup = BeautifulSoup(response, "html.parser")

# 파싱된 HTML 문서에서 모든 <div> 태그를 찾아서 tmp 변수에 저장
tmp = soup.find_all('div')

 

해당 코드를 테스트 해본다.

tmp_list = []
for line in tmp:
    tmp_list.append(line.text)

tmp_list

지식인 검색결과 가져오기


검색 결과 불러오기

 

이제 해당 검색어로된 지식인 검색 결과를 읽어온다. (검색결과 수가 많기 때문에 비교적 많은 시간 소요)

# tqdm 라이브러리에서 tqdm_notebook 모듈을 import
from tqdm import tqdm_notebook

# 여자친구 선물에 대한 후보 텍스트를 저장할 빈 리스트 생
present_candi_text = []

# 1부터 9999까지 10 간격으로 반복하는 반복문
for n in tqdm_notebook(range(1, 10000, 10)):
# 여자친구 선물에 대한 검색 결과를 가져오기 위해 URL을 생성하고, 해당 페이지의 HTML을 가져
    response = urlopen(html.format(num=n,
                                   key_word=urllib.parse.quote('여자친구 선물')))

# BeautifulSoup을 사용하여 HTML을 파싱
    soup = BeautifulSoup(response, "html.parser")

# HTML에서 모든 <div> 태그를 찾아서 가져옴
    tmp = soup.find_all('div')

# 각 태그에서 텍스트를 추출하여 present_candi_text 리스트에 추가 
    for line in tmp:
        present_candi_text.append(line.text)
        
# 서버에 부담을 주지 않기 위해 0.5초의 간격을 두고 잠시 대기
    time.sleep(0.5)

※ 'Error displaying widget'  에러 메시지가 나오면, (실행 상태바가 안 나오면)

ipywidgets 라이브러리의 버전을 확인하고, 최신 버전으로 업데이트 하면 된다.

(현재 굳이 필요하지 않아서 적용하지는 않았다. 그리고 위 분석에 시간이 좀 오래 걸린다. 파이썬 소스 코드에는 먼저 실행할 수 있도록 순서를 지정해두었다.)

!pip show ipywidgets
!pip install ipywidgets --upgrade

 

시간을 좀 기다렸는데, 한 가지 관과한게 있었다.

네이버에서는 이런 웹 스크래핑을 차단하고 있다는 것이다.

(에러 메세지: HTTPError: HTTP Error 403: Forbidden ▶ 서버에서 사람이 아닌 자동으로 내용을 읽는 Spider/Bot 으로 판단하여 차단)

 

이런 경우에 headers를 설정하여 User-Agent 를 지정해주면 된다.

 

[관련 분석 내용 참고]

 

[파이썬] 시카고 맛집 분석-2

시작에 앞서해당 내용은 -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.<span style="font-fam..

puppy-foot-it.tistory.com

 

 

3장에서 가격과 주소 불러오는 코드에서 'HTTPError: HTTP Error 403: Forbidden' 에러 · Issue #100 · PinkWink/Da

price = [] address = [] for n in df.index[:3]: html = urlopen(df['URL'][n]) soup_tmp = BeautifulSoup(html, 'lxml') gettings = soup_tmp.find('p', 'addy').get_text() price.append(gettings.split()[0][...

github.com


◈ 그런데... 네이버에서 이마저도 막아뒀는지, 자꾸 HTTP Error 403: Forbidden 뜬다.

과거 진행했던 내용, 구글링을 통해 진행했던 방법을 써도 다 막히고 있다.

해결하기 위해 몇 시간을 계속 붙잡고 시도했다.

 

한참을 뒤적이다, 아래의 코드를 입력했고 처음으로 에러가 뜨지 않았다.

import requests
from bs4 import BeautifulSoup
import time

# 검색할 질의어 설정
query = "여자 친구 선물"

# 검색 결과 페이지 URL
url = f"https://kin.naver.com/search/list.naver?query={query}"

# 리스트 초기화
present_candi_text = []

# 약 1만 개의 검색 결과를 가져오기 위해 1부터 10000까지 10 간격으로 반복
for start_num in range(1, 10001, 10):
    # 현재 페이지 URL
    page_url = f"{url}&start={start_num}"
    
    # HTTP GET 요청 보내고 응답 받기
    response = requests.get(page_url)
    
    # 응답이 성공적으로 왔는지 확인
    if response.status_code == 200:
        # BeautifulSoup을 사용하여 HTML 파싱
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 검색 결과에 해당하는 모든 질문 제목 가져오기
        titles = soup.select('.question_title span')
        
        # 가져온 질문 제목을 리스트에 추가
        for title in titles:
            present_candi_text.append(title.text.strip())
    else:
        # 응답이 성공적으로 오지 않은 경우 오류 메시지 출력
        print(f"Failed to retrieve page {start_num}")
    
    # 서버에 부담을 주지 않기 위해 0.5초의 간격을 두고 잠시 대기
    time.sleep(0.5)

# 결과 리스트 출력
print(present_candi_text)
<설명 - f 문자열 with Chat GPT>

f 문자열 포매팅은 파이썬 3.6부터 도입된 기능으로, 문자열 내에 변수 값을 삽입할 때 사용됩니다.
이 때문에 URL 주소 앞에 f를 붙이면 해당 URL 문자열 내에 변수를 포함할 수 있게 됩니다.

예를 들어, url 변수에 저장된 문자열은 "https://kin.naver.com/search/list.naver?query={query}"입니다.
여기서 {query} 부분은 검색할 질의어를 나타내는 변수입니다.
이때 f 문자열 포매팅을 사용하면 URL 문자열 내에서 변수를 직접 사용할 수 있습니다.
f 문자열을 사용하면 문자열 내에 중괄호 {} 안에 변수명을 넣어 변수의 값으로 치환할 수 있습니다.

따라서 f"https://kin.naver.com/search/list.naver?query={query}"는 {query} 부분이
query 변수의 값으로 치환되어 실제 URL 주소가 됩니다.
이렇게 함으로써 코드가 보다 동적으로 URL 주소를 생성할 수 있게 됩니다.

 

present_candi_text 변수
present_candi_text 변수에 아무것도 저장되지 않았다... 0_0

 

오류 코드 검색하는데 몇 시간, 리스트 저장하는데 십여분 걸렸는데 리스트에 저장된 값이 아무것도 없다니..

그래도 스크래핑 오류는 해결했으니, 이를 활용해봐야겠다.

 

너무 지쳐서 조금만 쉬었다 해야겠다.


다음 성공 버전

 

[파이썬] 자연어 처리(NLP) - 여자친구 선물 고르기 : 2(재도전)

시작에 앞서해당 내용은 -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.지난 챕터  [파이썬] 자연어 처리(NLP) - 여자친

puppy-foot-it.tistory.com

 

실패버전(크롤링 성공, 워드 클라우드 실패)

 

[파이썬] 자연어 처리(NLP) - 여자친구 선물 고르기 : 2(실패)

시작에 앞서해당 내용은 -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.지난 챕터 [파이썬] 자연어 처리(NLP) - 여자친

puppy-foot-it.tistory.com

 

728x90
반응형