빅데이터 프로그래밍/Python

[Python] 35. [Scraping] Open API를 활용한 데이터 수집, MySQL 서버로 수집된 데이터의 저장

밍글링글링 2017. 8. 21.
728x90

[01] Open API를 활용한 데이터 수집
- IE -> https://data.seoul.go.kr  -> 회원 가입 -> 로그인 -> 오픈 데이터 -> 오픈 API
 -> '지하철 승하차 인원' 검색 -> '서울시 지하철호선별 역별 승하차 인원 정보' 접속
 -> Open API -> 인증키 신청 -> 4d79514946696e753739665a4f5979

1. 하나의 날짜에대한 지하철 승하차 인원 정보
[실행 화면]
1호선 종각
loading_date: 20170423 일요일
승차 : 22966
하차 : 19138
 
▷ crawler1.subway1.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

from urllib.request import urlopen
from urllib.parse import quote
from bs4 import BeautifulSoup
import datetime
import random
import re
from urllib import request
import xml.etree.ElementTree as ET # XML 태그 접근 지원

apiKey = '4d79514946696e753739665a4f5979'
days = ['월요일', '화요일', '수요일', '목요일', '금요일', '토요일', '일요일']

def subper(sub) :
    LINE_NUM = sub.split(' ')[0] # 경부선 또는 1호선...
    subName = sub.split(' ')[1]   # 신도림 또는 종각

    current = datetime.datetime.now()  # 현재 시간 가져오기 
    # 5일 이전 날짜 계산
    loading_date = str(datetime.date.today() - datetime.timedelta(days=5))
    # 2017-04-25 → 20170425  
    loading_date = loading_date.replace('-','');
    
    # datetime.datetime.today().weekday(): 오늘 요일
    # datetime.datetime.strptime("2014-02-06", "%Y-%m-%d").date()
    # 0, 1, 2... 
    days_index = datetime.datetime.strptime(loading_date, "%Y%m%d").date().weekday()
    print('days_index: ' + str(days_index))
    print('loading_date: ' + loading_date + ' ' + days[days_index]); # 20170425 화요일
    
    url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+loading_date
    # url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+'20170424'
    # url: http://openapi.seoul.go.kr:8088/4d79514946696e753739665a4f5979/xml/CardSubwayStatsNew/1/549/20170424
    print('url: ' + url)
    
    # DOM 객체 생성, XML 태그 -> 객체로 변환
    tree = ET.ElementTree(file=urlopen(url)) 
    root = tree.getroot() # 최상위 태그 산출, 하나만 존재 <CardSubwayStatsNew>

    for data in root.iter("row") :  # <row> 산출
        # print('row: ' + str(data))
        
        # <row> 자식에서 1호선등 노선 검색 
        if data.findtext("LINE_NUM").find(LINE_NUM) != -1 :
            # 역명 검색
            if data.findtext("SUB_STA_NM").find(subName) != -1 :
                string = "승차 : {0}\n하차 : {1}".format(data.findtext("RIDE_PASGR_NUM"), data.findtext("ALIGHT_PASGR_NUM"))
                return string

if __name__ == "__main__" :
    station = '1호선 종각'
    print(station)
    print(subper(station))
    
-------------------------------------------------------------------------------------​

 
 
 
 
2. 여러 날짜와 여러역에 대한 지하철 승하차 인원 정보
[실행 화면]
['경부선', ['신도림', '영등포', '대방', '노량진', '용산', '남영', '서울역', '시청']]
조회할 역의 수: 8
0
1
2
3
4
5
6
7
신도림
영등포
대방
노량진
용산
남영
서울역
시청
---------------------------------
loading_date: 20170423 일요일
서울역 승차 : 6977 하차 : 645
남영 승차 : 6401 하차 : 7061
용산 승차 : 37666 하차 : 33642
노량진 승차 : 13281 하차 : 12336
대방 승차 : 9040 하차 : 9081
영등포 승차 : 45742 하차 : 45835
신도림 승차 : 2842 하차 : 2787
 
▷ crawler1.subway2.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

from urllib.request import urlopen
from urllib.parse import quote
from bs4 import BeautifulSoup
import datetime
import random
import re
from urllib import request
import xml.etree.ElementTree as ET

apiKey = '4d79514946696e753739665a4f5979'
days = ['월요일', '화요일', '수요일', '목요일', '금요일', '토요일', '일요일']
string=''

def subpercent(sub) :
    global string
    LINE_NUM = sub[0] # 1호선
    subName = sub[1]  # 역 list
    
    print('조회할 역의 수: ' + str(len(subName)))
    
    for count in range(len(subName)): # 0 ~ 7
        print(str(count))
    
    for subNameItem in subName:  # 역 이름 출력
        print(subNameItem)
        
    print('---------------------------------')    
    
    current = datetime.datetime.now()  # 현재 시간 가져오기 
    loading_date = str(datetime.date.today() - datetime.timedelta(days=5))  
    loading_date = loading_date.replace('-','');
    
    # datetime.datetime.today().weekday(): 오늘 요일
    # datetime.datetime.strptime("2014-02-06", "%Y-%m-%d").date()
    days_index = datetime.datetime.strptime(loading_date, "%Y%m%d").date().weekday()
    # loading_date: 20170604 일요일
    print('loading_date: ' + loading_date + ' ' + days[days_index]);
    
    url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+loading_date
    # url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+'20170424'
    # url: http://openapi.seoul.go.kr:8088/4d79514946696e753739665a4f5979/xml/CardSubwayStatsNew/1/549/20170424
    print('url: ' + url)
    
    tree = ET.ElementTree(file=urlopen(url))
    root = tree.getroot() # CardSubwayStatsNew 루트 태그

    for data in root.iter("row") : # row 태그
        # print('row: ' + str(data))
        
        # 호선 이름이 존재하는가? 없으면 -1
        if data.findtext("LINE_NUM").find(LINE_NUM) != -1 :
            for subNameItem in subName:
                # 역이름이 존재하는가?
                if data.findtext("SUB_STA_NM").find(subNameItem) != -1 :
                    print(subNameItem, end=' ') # 역이름 출력후 라인 변경 안함
                    print('승차 : {0}'.format(data.findtext("RIDE_PASGR_NUM")), end=' ')
                    print('하차 : {0}'.format(data.findtext("ALIGHT_PASGR_NUM")))

                 
if __name__ == "__main__" :
    station = ['경부선',['신도림','영등포','대방','노량진','용산','남영','서울역','시청']]
    print(station)
    subpercent(station)


  
-------------------------------------------------------------------------------------​

 
 

3. Python과 MySQL 5.6 연동 
- 여러 날짜와 여러역에 대한 지하철 승하차 인원 정보를 MySQL 서버에 저장하기


C:\Users\soldesk>pip install PyMySQL
Collecting PyMySQL
  Downloading PyMySQL-0.7.11-py2.py3-none-any.whl (78kB)
    100% ■■■■■■■■■■ 81kB 110kB/s
Installing collected packages: PyMySQL
Successfully installed PyMySQL-0.7.11

 
1) SQL
[실행 화면]
 
▷ crawler1.subway3.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

from urllib.request import urlopen
from urllib.parse import quote
from bs4 import BeautifulSoup
import datetime
import random
import re
from urllib import request
import xml.etree.ElementTree as ET
import pymysql.cursors 

connection = pymysql.connect(host='172.16.3.100',
                             user='python100',
                             password='1234',
                             db='python100',
                             charset='utf8')

apiKey = '4d79514946696e753739665a4f5979'
days = ['월요일', '화요일', '수요일', '목요일', '금요일', '토요일', '일요일']
string=''

def subpercent(sub) :
    global string
    LINE_NUM = sub[0] # 1호선
    subName = sub[1]  # 역 list
    print('조회할 역의 수: ' + str(len(subName)))
    for count in range(len(subName)):
        print(str(count))
    for subNameItem in subName:
        print(subNameItem)
    print('---------------------------------')    
    
    current = datetime.datetime.now()  # 현재 시간 가져오기 
    loading_date = str(datetime.date.today() - datetime.timedelta(days=6))  
    loading_date = loading_date.replace('-','');
    
    # datetime.datetime.today().weekday(): 오늘 요일
    # datetime.datetime.strptime("2014-02-06", "%Y-%m-%d").date()
    days_index = datetime.datetime.strptime(loading_date, "%Y%m%d").date().weekday()
    print('loading_date: ' + loading_date + ' ' + days[days_index]);
    
    url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+loading_date
    # url = 'http://openapi.seoul.go.kr:8088/'+apiKey+'/xml/CardSubwayStatsNew/1/549/'+'20170424'
    # url: http://openapi.seoul.go.kr:8088/4d79514946696e753739665a4f5979/xml/CardSubwayStatsNew/1/549/20170424
    print('url: ' + url)
    
    tree = ET.ElementTree(file=urlopen(url))
    root = tree.getroot()

    for data in root.iter("row") :
        # print('row: ' + str(data))
        
        if data.findtext("LINE_NUM").find(LINE_NUM) != -1 :
            for subNameItem in subName:
                if data.findtext("SUB_STA_NM").find(subNameItem) != -1 :
                    print(subNameItem, end=' ')
                    RIDE_PASGR_NUM = data.findtext("RIDE_PASGR_NUM")
                    ALIGHT_PASGR_NUM = data.findtext("ALIGHT_PASGR_NUM")
                    print('승차 : ' + RIDE_PASGR_NUM, end=' ')
                    print('하차 : ' + ALIGHT_PASGR_NUM)

                    with connection.cursor() as cursor:
                        '''
                        sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
                        cursor.execute(sql, ('webmaster@python.org', 'very-secret'))
                       '''
                        sql="""
                        INSERT INTO subway(loading_date, line_num, subNameItem, ride_pasgr_num, alight_pasgr_num)
                        VALUES(%s, %s, %s, %s, %s)
                        """
                        cursor.execute(sql, (loading_date, LINE_NUM, subNameItem, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM))

                        connection.commit()
               
if __name__ == "__main__" :
    station = ['경부선',['신도림','영등포','대방','노량진','용산','남영','서울역','시청']]
    print(station)
    subpercent(station)


  
-------------------------------------------------------------------------------------​

 
 
 
3. MySQL SELECT

1) SQL

[실행 화면]
20170423 경부선 남영 6401 7061
20170423 경부선 노량진 13281 12336
20170423 경부선 대방 9040 9081
20170423 경부선 서울역 6977 645
20170423 경부선 신도림 2842 2787
20170423 경부선 영등포 45742 45835
20170423 경부선 용산 37666 33642
 
▷ crawler1.subway4.py
-------------------------------------------------------------------------------------
# -*- coding: utf-8 -*-

from urllib.request import urlopen
from urllib.parse import quote
from bs4 import BeautifulSoup
import datetime
import random
import re
from urllib import request
import xml.etree.ElementTree as ET
import pymysql.cursors

connection = pymysql.connect(host='172.16.3.100',
                             user='python100',
                             password='1234',
                             db='python100',
                             charset='utf8')

try:
    with connection.cursor() as cursor:
        sql="""
        SELECT loading_date, line_num, subNameItem, ride_pasgr_num, alight_pasgr_num
        FROM subway
        ORDER BY loading_date DESC, line_num ASC, subNameItem ASC
        """
        cursor.execute(sql)
        rs = cursor.fetchall() # 레코드 목록
        for row in rs:
            # ('20170423', '경부선', '남영', 6401, 7061)
            # print(row)
            print(row[0], row[1], row[2], row[3], row[4])
    
except Exception as e:
    pass



-------------------------------------------------------------------------------------
 
 
 

 

728x90

댓글