안경잡이개발자

728x90
반응형

웹 크롤러(Web Crawler)로 연속적인 크롤링하기

나동빈


  지난 시간에 이어서 웹 크롤러를 이용해 연속적인 크롤링 방법에 대해 알아보는 시간을 가져보겠습니다.


  이번 시간의 실습 대상은 다양한 영어 대화(English Conversation) 스크립트를 제공하는 웹 사이트입니다.


  웹 사이트: https://basicenglishspeaking.com/daily-english-conversation-topics/



  웹 사이트에 접속하면 위와 같이 75개의 주제(Topic)이 나오는 것을 알 수 있습니다. 일단 전체 주제의 개수가 총 몇 개인지 자동으로 세주도록 해봅시다. '페이지 소스 코드'를 보시면 다음과 같이 클래스명에 따라서 내용이 구분되는 것을 확인할 수 있습니다.



  따라서 먼저 전체 주제의 개수를 찾을 수 있도록 프로그램을 작성해보겠습니다.


from bs4 import BeautifulSoup

import requests


# 한 건의 대화에 대한 정보를 담는 객체입니다.

class Conversation:

    # 질문(Question), 응답(Answer) 두 변수로 구성됩니다.

    def __init__(self, question, answer):

        self.question = question

        self.answer = answer

        

    def __str__(self):

        return "질문: " + self.question + "\n답변: " + self.answer + "\n"


# 모든 영어 대화 주제를 추출하는 함수입니다.

def get_subjects():

    subjects = []


    # 전체 주제 목록을 보여주는 페이지로의 요청(Request) 객체를 생성합니다.

    req  = requests.get('https://basicenglishspeaking.com/daily-english-conversation-topics/')

    html = req.text

    soup = BeautifulSoup(html, 'html.parser')


    divs = soup.findAll('div',{"class": "su-column-inner"})

    for div in divs:

        # 내부에 존재하는 <a> 태그들을 추출합니다.

        links = div.findAll('a')


        # <a> 태그 내부의 텍스트를 리스트에 삽입합니다.

        for link in links:

            subject = link.text

            subjects.append(subject)

    

    return subjects


subjects = get_subjects()


print('총 ', len(subjects), '개의 타입을 찾았습니다.')


print(subjects)



  성공적으로 75개의 주제를 찾아서 출력한 것을 확인할 수 있습니다. 이제 이어서 실질적으로 각각의 주제에 포함되어 있는 영어 대화 스크립트를 추출할 수 있는 소스코드를 작성해봅시다.



예를 들어 'Family'로 요청(Request) URL을 설정하여 들어가면 위와 같이 다양한 영어 대화 스크립트가 존재합니다.



마찬가지로 '페이지 소스 보기'를 통해 소스코드를 확인했을 때 일정한 규칙이 존재하는 것을 확인할 수 있습니다.


위에서 제시한 소스코드에 이어서 다음과 같이 소스코드를 작성하여 모든 주제에 대한 대화 스크립트를 가져 올 수 있도록 합니다.


conversations = []

i = 1


# 모든 대화 주제 각각에 접근합니다.

for sub in subjects:

    print('(', i, '/', len(subjects), ') ', sub)

    # 대화 스크립트를 보여주는 페이지로의 요청(Request) 객체를 생성합니다.

    req  = requests.get('http://basicenglishspeaking.com/' + sub)

    html = req.text

    soup = BeautifulSoup(html, 'html.parser')

    

    qnas = soup.findAll('div',{"class": "sc_player_container1"})


    # 각각의 대화 내용에 모두 접근합니다.

    for qna in qnas:

        if qnas.index(qna) % 2 == 0:

            q = qna.next_sibling

        else:

            a = qna.next_sibling

            c = Conversation(q, a)

            conversations.append(c)

            

    i = i + 1

            

print('총 ', len(conversations), '개의 대화를 찾았습니다.')


for c in conversations:

    print(str(c))



728x90
반응형