본문 바로가기

IT

[Python] Web Crawling for Melon

야매코더이기 때문에 코드가 많이 더럽다.

나중에 정리하자...

 

1. 목적: 멜론에서 특정 가수의 발매 곡 목록 전부를 크롤링함 (기존 정보들은 대부분 Top 100 차트에 관한 내용)

 

2. 개발 환경: Python 3.7.3 (확인방법: Anaconda Prompt > python --version 입력)

1) 크롤링 라이브러리: scrapy

2) 크롤링 결과 저장 라이브러리: json

 

# -*- coding: utf-8 -*-

import scrapy
import json

class MySpider(scrapy.Spider):
    # spider 이름
    name = "melon"
    
    # 크롤링 시작할 URL 리스트
    start_urls = [
    #AOA
    'https://m2.melon.com/cds/artist/mobile4web/artist_songList.htm?startIndex=1&pageSize=20&rowsCnt=20&artistId=686920&filterBy=A&orderBy=NEW',
    ]

    def parse(self, response):
 
        for quote in response.css('li.list_item'):
            yield {
                'title'  : quote.xpath('div[2]/div/a/p').extract_first().replace('<span class=\"sprite title hide\">', '').replace('<p class=\"title ellipsis\">', '').replace('</p>', '').replace('\ud0c0\uc774\ud2c0</span>', '').replace('<span class=\"sprite limit19 hide\">19\uae08</span>', '').strip(),
                'songId' : quote.xpath('div[2]/div/a/@href').extract_first().replace("javascript:goDetail('song','", '').replace(')', '').replace("'", ''),
                'artist' : quote.xpath('div[2]/div/a/span/text()').extract_first(),
                'img'    : quote.xpath('div[1]/div/a/span[@class="img"]/@style').extract_first().replace('background-image:url(//', '').replace(')', ''),
            }

 

css와 xpath 잠깐 들여다 보기

css) li.list_item > li 구문에서 class = 'list_item'인 것

xpath) div[2]/div > 같은 계층에 div가 여러 개 있을 경우, 두 번째 div 구문을 지칭하며, 그 아래 계층에 있는 div 의미

 

 

 

3. 진행 중 예상치 못한 사항

1) scrapy import 에러

scrapy는 pip install scrapy 대신 아래 코드를 사용하여 라이브러리를 설치하기를 권장한다. pip으로 설치했는데 안돼서 검색하다가 *conda로 재설치를 했다. 그런데도 안돼서 재부팅했더니 잘 된다. ^^?

(* 파이썬 3.5 이상 버전에서 작동 참조)

conda install -c conda-forge scrapy

 

 

2) Pagination 문제

음원사이트는 곡 목록을 보여주는 경우 보통 20개를 띄워주고, (더보기 또는 다음 페이지) 버튼을 눌러 남은 목록을 노출시키게 구성해놨다. 크롬 기준으로 F12를 눌러 페이지 소스를 확인할 수 있다. 

 

3) PC에서 모바일 웹 버전으로 접속하려면? ☞ 참조

 

 

4) 인코딩 문제

json 파일에서 한글이 유니코드 형태로 출력되는 문제가 발생한다.

scrapy를 통해 추출한 json 형식의 데이터

그런데 이상하게 아나콘다 프롬프트나 주피터에서는 한글이 잘 출력된다. 이해할 수 없다. 아나콘다 프롬프트는 ANSI 기반이다. (확인방법: 아나콘다 프롬프트 > 윈도우 바 우클릭 > 속성 > 현재 코드 페이지 부분) 주피터는 모르겠다.

 

 

인코딩 문제를 위해 시도한 방법들

더보기

파이썬 3 버전은 자동으로 utf-8을 세팅해서 아래의 코드는 필요 없다.

# -*- coding: utf-8 -*-

아래 코드는 파이썬 2 버전에서 작동하며, 마찬가지로 필요 없는 코드이다. 그대로 실행하면 파이썬 3에서는 에러가 난다.

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

프로젝트의 settings.py 파일에 하단부에 아래 코드를 추가해도 해결되지 않았다.

FEED_EXPORT_ENCODING = 'utf-8'

봐도 이해 안가지만 혹시나 해서 가져오는 링크.

https://doc.scrapy.org/en/1.2/topics/feed-exports.html#std:setting-FEED_EXPORT_ENCODINGhttps://stackoverflow.com/questions/9181214/scrapy-text-encoding

 

아무튼 여전히 유니코드로 출력이 됐다.

 

하... 짜증나...

 

그래서 우회 방법으로 json 파일을 읽어서 csv 파일로 변환시켜주는 코드를 추가하였다.

다음 글에서 확인 seohyunc.tistory.com/3