Skip to content

Instantly share code, notes, and snippets.

@allieus
Last active September 15, 2017 03:28
Show Gist options
  • Save allieus/2de83c8f8b7b06d33381323a9b7c593d to your computer and use it in GitHub Desktop.
Save allieus/2de83c8f8b7b06d33381323a9b7c593d to your computer and use it in GitHub Desktop.

파이콘에서 "케이블 영화 채널 편성표 수집하기" 세션 잘 들었습니다. (세션 페이지)

이는 페이징와 화면 렌더링 처리가 javascript로 되어있기 때문 여러 채널 수집에 Selenium을 쓰셨더라구요.

이 부분에 대해 requests를 통해 처리하는 샘플코드를 간략하게나마 작성해봤습니다.

참고한 세션 코드 저장소 : https://github.com/rubysoho07/MovieScheduler/blob/master/scheduler_core/tests.py

아래 소스코드를 참고해서, requests를 통해 보다 효율적으로 페이징 크롤링을 해보세요.

필요한 라이브러리 설치

pip install requests demjson

By AskDjango

여러분의 파이썬/장고 페이스메이커가 되겠습니다.

import demjson
import json
import re
import requests
# 실제 웹페이지에서는 쿼리인자를 JS를 통해 POST로 넘기지만,
# GET으로 넘겨도 동일하게 동작하더라구요.
url = "http://www.imtcast.com/screen/program/schedule.jsp?stdDate=20170807&toDate="
params = {
"stdDate": "20170807",
"toDate": "",
}
html = requests.get(url, params=params).text
# 데이터가 javascript object로서 표현이 되어있습니다.
# 그래서, 이 부분을 정규 표현식으로 뽑아냈습니다.
matched = re.search(r'var schedule\s*=\s*(.*?);', html, re.MULTILINE | re.DOTALL)
javascrit_obj_string = matched.group(1)
# 뽑아낸 javascript object 문자열은 json포맷이 아니기 때문에,json.loads를 통해 처리하지 못합니다.
# 이를 처리해주는 demjson라이브러리를 통해 객체로 변환했습니다.
obj = demjson.decode(javascrit_obj_string)
# 이제 다음과 같이 활용하실 수 있습니다. ;)
print(obj.keys()) # 실행결과 : dict_keys(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'])
print(obj['mon']) # 실행결과 : 3_output.py 참조
# by AskDjango
[{'caption_yn': '',
'cont': '05',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '에로',
'pgm_cd': 'S2017-0112',
'pgm_grd': '19',
'pgm_nm': '아내의사정',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '05:20',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '06',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '판타지',
'pgm_cd': 'S2015-0152',
'pgm_grd': '15',
'pgm_nm': '솔로몬케인',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '06:25',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '07',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '판타지',
'pgm_cd': 'S2015-0152',
'pgm_grd': '15',
'pgm_nm': '솔로몬케인',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '07:25',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '08',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2013-0030',
'pgm_grd': '15',
'pgm_nm': 'S.W.A.T특수기동대',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '08:25',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '09',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2013-0030',
'pgm_grd': '15',
'pgm_nm': 'S.W.A.T특수기동대',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '09:35',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '10',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2013-0318',
'pgm_grd': '15',
'pgm_nm': '버니드롭',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '10:45',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '11',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2013-0318',
'pgm_grd': '15',
'pgm_nm': '버니드롭',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '11:55',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '12',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '',
'pgm_cd': '',
'pgm_grd': '',
'pgm_nm': '',
'pgm_seq': '',
'pgmid': '',
'pgmtime': '',
'pgmymd': '',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '13',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2016-0261',
'pgm_grd': '15',
'pgm_nm': '코드오브아너',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '13:05',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '14',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2016-0261',
'pgm_grd': '15',
'pgm_nm': '코드오브아너',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '14:10',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '15',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2017-0156',
'pgm_grd': '15',
'pgm_nm': '라스트스탠드',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '15:15',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '16',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2017-0156',
'pgm_grd': '15',
'pgm_nm': '라스트스탠드',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '16:15',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '17',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2016-0225',
'pgm_grd': '15',
'pgm_nm': '킥복서리턴즈',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '17:20',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '18',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '',
'pgm_cd': '',
'pgm_grd': '',
'pgm_nm': '',
'pgm_seq': '',
'pgmid': '',
'pgmtime': '',
'pgmymd': '',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '19',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '기타',
'pgm_cd': 'S2014-0274',
'pgm_grd': '15',
'pgm_nm': '위클리영화의발견',
'pgm_seq': '124',
'pgmid': '15854870',
'pgmtime': '19:05',
'pgmymd': '20170807',
'relationsiteurl': 'http://www.imtcast.com/screen/weeklymagazine',
'sin_lng_yn': '',
'vodcnt': '280'},
{'caption_yn': 'Y',
'cont': '19',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2016-0243',
'pgm_grd': '15',
'pgm_nm': 'CSI:NY6',
'pgm_seq': '11',
'pgmid': '85530918',
'pgmtime': '19:45',
'pgmymd': '20170807',
'relationsiteurl': 'http://www.imtcast.com/screen/CSINY6',
'sin_lng_yn': '',
'vodcnt': '0'},
{'caption_yn': 'Y',
'cont': '20',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2016-0243',
'pgm_grd': '15',
'pgm_nm': 'CSI:NY6',
'pgm_seq': '12',
'pgmid': '85530918',
'pgmtime': '20:45',
'pgmymd': '20170807',
'relationsiteurl': 'http://www.imtcast.com/screen/CSINY6',
'sin_lng_yn': '',
'vodcnt': '0'},
{'caption_yn': 'Y',
'cont': '21',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '판타지',
'pgm_cd': 'S2017-0171',
'pgm_grd': '15',
'pgm_nm': '왕좌의게임7-15세',
'pgm_seq': '3',
'pgmid': '',
'pgmtime': '21:50',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': '',
'cont': '22',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '',
'pgm_cd': '',
'pgm_grd': '',
'pgm_nm': '',
'pgm_seq': '',
'pgmid': '',
'pgmtime': '',
'pgmymd': '',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '23',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2016-0051',
'pgm_grd': '15',
'pgm_nm': '이탈리안잡',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '23:10',
'pgmymd': '20170807',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '00',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2016-0051',
'pgm_grd': '15',
'pgm_nm': '이탈리안잡',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '00:20',
'pgmymd': '20170808',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '01',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2016-0245',
'pgm_grd': '15',
'pgm_nm': 'CSI:NY9',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '01:25',
'pgmymd': '20170808',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '02',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '드라마',
'pgm_cd': 'S2016-0245',
'pgm_grd': '15',
'pgm_nm': 'CSI:NY9',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '02:25',
'pgmymd': '20170808',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '03',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2017-0125',
'pgm_grd': '15',
'pgm_nm': '토너먼트',
'pgm_seq': '1',
'pgmid': '',
'pgmtime': '03:25',
'pgmymd': '20170808',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''},
{'caption_yn': 'Y',
'cont': '04',
'ctsid': '',
'dvs_yn': '',
'event_idx': '',
'jenr_gb': '액션',
'pgm_cd': 'S2017-0125',
'pgm_grd': '15',
'pgm_nm': '토너먼트',
'pgm_seq': '2',
'pgmid': '',
'pgmtime': '04:25',
'pgmymd': '20170808',
'relationsiteurl': '',
'sin_lng_yn': '',
'vodcnt': ''}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment