Ver.0.1 : 20220517 - 상렬
Requests
모듈 기반 지식인 크롤링에 대한것import requests
import pandas as pd
from tqdm import tqdm
from bs4 import BeautifulSoup
#import ssl
'''
url -> 지식인 특정 카테고리에 Q&A를 긁는 기본 base url이다. 적어도 질문에 대한 답변이 하나는 존재한다
Q&A >교육,학문 > 중학교교육 > 사회 : 110302
'''
def crawl_kin(page_n:int, category_num:int):
'''
기본적으로 게시판에는 20개의 게시글이 있고 총 긁어올 정보는 20 x page_n만큼의 QA 정보입니다.
category는 지식인의 어느 보드를 긁어올것인가에 대한 인자입니다.
'''
idx = 0
accepta = None
web_df = pd.DataFrame(columns=('category', 'question', 'answer_1', 'answer_2', 'answer_3', 'accept'))
detail_url = '<https://kin.naver.com/qna/detail.naver?'>
try:
for page in tqdm(range(1, page_n+1)):
web_df_column = []
url = f'<https://kin.naver.com/qna/kinupList.naver?dirId={category_num}&page={page}>'
response = requests.get(url)
if response.status_code == 200:
for id in range(1,21):
#한 게시판에 게시글이 20개씩있고 이것을 pagenation에 대해서 옮겨가야함
html = response.text
soup = BeautifulSoup(html, 'html.parser')
ul = soup.find('tbody', id='au_board_list')
titles = ul.select(f'tr:nth-child({id}) > td.title > a')
category = ul.select(f'#au_board_list > tr:nth-child({id}) > td.field > a')[0].text
for a in titles:
href = detail_url + a.get('href').split('?')[1]
detail = requests.get(href)
detail_html = detail.text
detail_soup = BeautifulSoup(detail_html, 'html.parser')
detail_title = detail_soup.find('div', "c-heading__content")
if detail_title != None:
detail_title = detail_title.text.strip()
else:
detail_title = "NaN"
#content > div.question-content > div > div.c-heading._questionContentsArea.c-heading--default-old > div.c-heading__title > div > div
detail_content = detail_soup.find('div', "answer-content__list _answerList")
web_df_column = [category, detail_title]
for x in range(1,4):
answers = None
try:
answers = detail_content.select_one(f'#answer_{x} > div._endContents.c-heading-answer__content > div._endContentsText.c-heading-answer__content-user')
accept = detail_content.select_one(f'#answer_{x} > div.c-heading-answer > div.c-heading-answer__body > div.adopt-check-box > span')
if answers != None:
web_df_column.append(answers.text.strip())
else:
web_df_column.append("NaN")
if accept != None:
accepta = x
except:
pass
web_df_column.append(accepta)
web_df.loc[idx] = web_df_column
idx += 1
else :
print(response.status_code)
print(page)
break
except:
pass
web_df.to_csv(f"./{page_n * 20}_{category_num}.csv", index=False)
crawl_kin(100, 110302)
예시)
<aside> 💡 Q. 사회.csv 를 봤는데 NaN과 11같은 값이 있습니다..! 혹시 이건 어떤 것일까요? 또한, 생각해보니 정말 만일의 상황을 생각해서 해당 질문 링크도 meta 데이터로 들어오면 좋겠단 생각이 들었습니다! @seyeon park
</aside>
<aside> 💡 Q. 지식인이 Title-본문 내용-답변 pair로 이루어져 있는데요, Title에서 질문 내용을 전부 쓰고 본문 내용을 쓰지 않아서 현재 본문 내용에서 뽑아오고 있는 Qustion이 NaN으로 뜨는 경우가 과학 카테고리에서는 많이 존재합니다. Title+본문 내용을 묶어 Qustion으로 함께 쓰는 방법을 제안합니다. @Sangryul Kim
</aside>
A) 아 다른 분야에서는 그문제가 두드러지는군요. 네네 그 부분을 하면 좋을것 같습니다.
<aside> 💡 코드상에서 채택(accept)된 문서가 없을 경우, 제대로 초기화 되지 않아 이전에 채택된 문서 index를 참고하는 문제를 수정해두었습니다. 업데이트된 코드를 사용하시면 좋을 것 같습니다.(데이터 → 지식인 크롤링 - 과학 과목) @Sangryul Kim
</aside>
A) 오류 수정 감사합니다!! 🙂아직 저희가 프로젝트 github를 슬랙에서 이후에 논의하기로 한것 같은데 버전별 관리를 github 설정 이후에 바로 들어가고, 또 코드부분에 대해서도 기존 ipynb파일에 대해서 오류 부분 수정하고 또 어느정도 pilot 끝났으면 .py 형태로 코드 관리를 하는것도 좋아보입니다. @seyeon park
A) .py 형태로 추가해두겠습니다.
python 3.8.13
Ubuntu
beautifulsoup4==4.11.1 requests==2.27.1
pandas == 1.4.2