서울시 시위정보를 가져오고자 했다.
서울시 시위정보는 아래의 사이트에서 확인이 가능하다.
https://www.smpa.go.kr/user/nd54882.do
시위 목록이 여러가지가 있는데 각각 클릭시 이동하는 링크는
https://www.smpa.go.kr/user/nd54882.do?View&uQ=&pageST=SUBJECT&pageSV=&imsi=imsi&page=1&pageSC=SORT_ORDER&pageSO=DESC&dmlType=&boardNo=00288890&returnUrl=https://www.smpa.go.kr:443/user/nd54882.do
다음과 같은데 boardNo를 제외한 나머지는 고정이다.
boardNo를 가져오는 방법은
href에 있기 때문에
selector = "#subContents > div > div.inContent > table > tbody > tr:nth-child(1) > td.subject > a"
html = requests.get("https://www.smpa.go.kr/user/nd54882.do")
soup = BeautifulSoup(html.text, 'html.parser').select_one(selector)
time = soup.text.split(" ")[2]
href_data = soup['href'].split(",")[2][1:9]
위의 코드를 통해 가져올 수 있다. time은 시위 날짜, href_data는 boardNo를 저장한 변수이다.
이제는 링크로 이동하여, pdf 파일을 받아보자.
위의 그림을 보면 3가지 형식의 파일로 다운이 가능하다.
hwp, jpg, pdf
pdf를 다운 받아 csv형태로 바꿔 데이터를 저장하고자 했다.
데이터 업데이트는, 전날에 이루어진다. 하지만 주말의 경우에는 (토요일, 일요일) 한번에 업데이트 되고, 시위정보는 시위가 일어나고 다음에 알 필요가 없기 때문에 미리 가능한 많은 시위 데이터를 가져오고자 했다.
pdf를 다운받기 위한 url를 찾고자 했다.
여기서 봐야할 점은 첨부파일에서 pdf파일을 클릭 했을 때, attatchfileDownload라는 함수가 실행된다는 점이다.
attatchfileDownload 함수는 contextPath와 attachNo를 인자로 받는다, contextPath의 경우에는 고정되어 있지만, attatchNo에 따라 다운로드되는 파일이 달라진다.
attatchNo를 가져오는 코드이다.
url = "https://www.smpa.go.kr/user/nd54882.do?View&uQ=&pageST=SUBJECT&pageSV=&imsi=imsi&page=1&pageSC=SORT_ORDER&pageSO=DESC&dmlType=&boardNo={}&returnUrl=https://www.smpa.go.kr:443/user/nd54882.do".format(href_data)
html = requests.get(url)
selector = "#subContents > div > div.inContent > table > tbody > tr:nth-child(3) > td > a:nth-child(5)"
soup = BeautifulSoup(html.text,'html.parser').select_one(selector)
number = soup["onclick"].split(",")[1][1:9]
받은 pdf파일을 tabula를 통해 csv 파일로 바꾸기
try:
file = self.path + self.now +".pdf"
df = read_pdf(file,pages='all')[0]
tabula.convert_into(file, self.path + self.now+".csv", output_format="csv",pages='all')
except Exception as e:
print(e)
전체 코드
import datetime
import os.path
from os import rename,listdir
import requests
from bs4 import BeautifulSoup
import tabula
from tabula import read_pdf
import time as TM
import urllib.request
import ssl
import pandas as pd
class PATH:
path = os.path.dirname(os.path.abspath(__file__)) + "/data/"
def setPath(self,path):
self.path = path
def getPath(self):
return self.path
class TIME:
def getTime(self):
return datetime.datetime.now().strftime("%y%m%d")
class Demontstration:
date = ""
place1 = ""
place2 = ""
peopleNum = ""
def __init__(self, date, place1, place2, peopleNume):
self.date = date
self.place1 = place1
self.place2 = place2
self.peopleNum = peopleNume
def printdDemonst(self):
print("시위 시각 : {}, 장소1 : {}, 장소2 : {}, 시위 인원 : {}".format(self.date, self.place1, self.place2, self.peopleNum))
class csvParse:
DemonList = []
def csvGetData(self, now):
csv_input = pd.read_csv(filepath_or_buffer="./data/"+now+".csv",sep=',')
df = csv_input.iloc[:,2:7]
tmpList = []
for i in range(0,len(csv_input),3):
date = csv_input[i+1:i+2]["집회 일시"].values[0]
peepleNum = csv_input[i+1:i+2]["신고 인원"].values[0]
ndf1 = df.iloc[i:i+1]
place1 = self.NumpyToStr(ndf1.dropna(axis=1).values)
ndf2 = df.iloc[i+2:i+3]
place2 = self.NumpyToStr(ndf2.dropna(axis=1).values)
tmpList.append(Demontstration(date,place1,place2,peepleNum))
self.DemonList.append(tuple((now, tmpList)))
def NumpyToStr(self,df):
return ' '.join(map(str,*df.tolist()))
class DATA:
clickList = []
updatelist = []
TIME = TIME()
def findData(self):
for i in range(1,4):
selector = "#subContents > div > div.inContent > table > tbody > tr:nth-child({}) > td.subject > a".format(i)
html = requests.get("https://www.smpa.go.kr/user/nd54882.do")
soup = BeautifulSoup(html.text, 'html.parser').select_one(selector)
time = soup.text.split(" ")[2]
href_data = soup['href'].split(",")[2][1:9]
self.updatelist.append(tuple((time,href_data)))
"""
체크할거 여기 추가해야함
"""
for i,j in self.updatelist:
url = "https://www.smpa.go.kr/user/nd54882.do?View&uQ=&pageST=SUBJECT&pageSV=&imsi=imsi&page=1&pageSC=SORT_ORDER&pageSO=DESC&dmlType=&boardNo={}&returnUrl=https://www.smpa.go.kr:443/user/nd54882.do".format(j)
html = requests.get(url)
selector = "#subContents > div > div.inContent > table > tbody > tr:nth-child(3) > td > a:nth-child(5)"
soup = BeautifulSoup(html.text,'html.parser').select_one(selector)
self.clickList.append(tuple((i,soup["onclick"].split(",")[1][1:9])))
class DataParse:
PATH = PATH()
path = PATH.path
fileList = listdir(path)
now = None
def ConvertExtension(self):
try:
file = self.path + self.now +".pdf"
df = read_pdf(file,pages='all')[0]
tabula.convert_into(file, self.path + self.now+".csv", output_format="csv",pages='all')
except Exception as e:
print(e)
def setNow(self,now):
self.now = now
if __name__ == "__main__":
ssl._create_default_https_context = ssl._create_unverified_context
DATA = DATA()
DATA.findData()
PATH = PATH()
DataParse = DataParse()
csvParse = csvParse()
for time, value in DATA.clickList:
print("{}의 데이터를 받았습니다.".format(time))
urllib.request.urlretrieve("https://www.smpa.go.kr/common/attachfile/attachfileView.do?attachNo={}".format(value),PATH.path + time+".pdf")
DataParse.setNow(time)
DataParse.ConvertExtension()
TM.sleep(5)
csvParse.csvGetData(time)
for time, Demonlist in csvParse.DemonList:
print("{} 시위정보 입니다.".format(time))
for value in Demonlist:
value.printdDemonst()
print()
결과