프로젝트/COHO - 코인 호재 캘린더

[Django] 코호 - 실시간 코인 호재 모음 PROC 2

모영이 2021. 3. 17. 16:12

순조롭게 진행되는 것 같았지만, 거대한 문제와 마주치게 될 것 같다.

 

해결한 문제

41페이지 전체를 크롤링 가능.

페이지 url은 뒤에 ?page=번호

이렇게 붙여주면 되기 때문에 1부터 계속 반복시키고, 만약 url이 없다면 반복문을 멈추도록 설계했다. 

 

페이지는 42페이지까지 존재하는데 html.status(url) 함수로 url존재 여부를 판단할 수 있다.

 

전체 코드

from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

month = { 'Jan' : 1, 'Feb' : 2, 'Mar' : 3, 'Apr' : 4, 'May' : 5, 'Jun' : 6, 'Jul' : 7, 'Aug' : 8, 'Sep' : 9, 'Oct' : 10, 'Nov' : 11, 'Dec' : 12 }

def coinmarketcalCrowler():

    def packingData(url : str):
        result = []

        html = urlopen(url)
        # 사이트에 문제가 있으면 함수 종료
        if html.status != 200:
            return
        soup = BeautifulSoup(html, "html.parser")

        # 정보 -> 이름, 호재 시간, 추가된 시간, 제목, 상세내용
        coin_name_data = soup.select("article.col-xl-3.col-lg-4.col-md-6.py-3 > div.card.text-center > div.card__body > h5.card__coins > a.link-detail")
        coin_goodnewstime_data = soup.select("h5[class = 'card__date mt-0']")
        coin_addedtime_data = soup.select("p[class = 'added-date']")
        coin_title_data = soup.select("article.col-xl-3.col-lg-4.col-md-6.py-3 > div.card.text-center > div.card__body > a.link-detail > h5.card__title.mb-0.ellipsis")
        coin_detail_data = soup.select("p[class = 'card__description']")

        min_len = min(len(coin_name_data), len(coin_goodnewstime_data), len(coin_addedtime_data), len(coin_title_data), len(coin_detail_data))

        # 전처리 이름[이름, 태그], 호재 시간[년, 월, 일], 추가된 시간[년, 월, 일], 제목[문자열], 상세내용[문자열]
        # 전처리 후 패킹
        for i in range(0, min_len):
            # 이름 전처리
            coin_name = ' '.join(coin_name_data[i].string.split())
            coin_name = [coin_name[0 : coin_name.find('(') - 1], coin_name[coin_name.find('(') + 1 : coin_name.find(')')]]
            # 호재 시간
            coin_goodnewstime = coin_goodnewstime_data[i].string.split()
            coin_goodnewstime = coin_goodnewstime[:3]
            coin_goodnewstime[1] = str(month[coin_goodnewstime[1]])
            coin_goodnewstime.reverse()
            # 추가된 시간
            coin_addedtime = coin_addedtime_data[i].string.split()
            coin_addedtime = coin_addedtime[1:]
            coin_addedtime[1] = str(month[coin_addedtime[1]])
            coin_addedtime.reverse()
            # 제목
            coin_title = coin_title_data[i].string
            # 상세내용
            coin_detail = ' '.join(coin_detail_data[i].string.split())

            # 패킹
            item_coin = {
                'name': coin_name,
                'goodnewstime': coin_goodnewstime,
                'addedtime': coin_addedtime,
                'title': coin_title,
                'detail': coin_detail
            }
            result.append(item_coin)

        return result

    result = []
    url = "https://coinmarketcal.com/en/"
    indx = 0
    while True:
        indx += 1
        one_data = packingData(url + "?page=" + str(indx))
        if one_data:
            result.extend(one_data)
        else:
            break
    return result

#시간 걸림..
for i in coinmarketcalCrowler():
    print(i)

 

해결해야 할 문제

위 코드를 돌렸을 때 2분 30초가 걸린다. 말도 안되는 속도다. 이를 해결할 방법을 찾아야 한다.

대충 찾아봤을 때 멀티프로세싱을 사용한다고 한다.