국회의원 상임위 활동 데이터 설명은
아래 link에 있습니다. .
https://open.assembly.go.kr/portal/data/service/selectAPIServicePage.do/OVW2NU000937WK15521#none
요청 주소
https://open.assembly.go.kr/portal/openapi/nuvypcdgahexhvrjt 에 대수, 회기, 차수, 위원회 등을 붙여서 호출하면 상임위 회의록 정보에 얻을 수
있습니다. 결과는 XML 형태이고 회의록 정보는 BILL_URL 태그에 있습니다.
이 BILL_URL를
접속해보면 개략적인 회의 순서만 볼 수 있고
순서를 클릭해야 상임위 회의록을 다운로드 받을 수 있습니다. 한두개의 회의록은 웹브라우저 클릭으로 구하는데 어려움이 없지만 천개 넘는 모든 상임위 회의록을 구하려면 자동화
방법이 필요합니다.
위 페이지의 소스를 보면 다운로드는 fn_fileDown() 를 호출해서 이루어집니다.
<ul>
<li><a href="#none"
onclick="javascript:fn_fileDown('049996','0000093499','P');"
title="개의">
fn_fileDown()는 이 파일에 구현되어 있습니다.
https://likms.assembly.go.kr/record/res/js/mhs/mhs40/mhs40.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | //보존부록 파일 다운로드 function fn_fileDown(conferNum,fileId){ // try{ // var $form = ""; // alert(conferNum+"/"+fileId); $form = $("<form></form>"); $form.attr("action", "mhs-10-040-0040.do"); $form.attr("target", "I_TARGET"); $form.attr("method", "post"); $form.append("<input name='conferNum' type='hidden' value='"+conferNum+"'>"); $form.append("<input name='fileId' type='hidden' value='"+fileId+"'>"); $form.append("<input name='deviceGubun' type='hidden' value='P'>"); // $form.appendTo('body'); // $form.submit(); // }catch(e){ alert("fn_fileDown" + "(" +e.name + ") : " + e.message); } // } |
conferNum, fileID,
deviceGubun를 넣어
POST 방식으로 호출하면 회의록 PDF파일을 구할 수 있습니다.
BILL_URL는 국회정보 일괄 다운로드 페이지에서도
일괄 구할 수 있습니다.
https://open.assembly.go.kr/portal/infs/list/infsListDownPage.do
결과물이 엑셀 파일이고 E열이 회의종류, F가 BILL_URL입니다.
이 엑셀 파일을 읽어 모든 상임위의 BILL_URL를 접근하고 beautifulsoup를 이용하여 conferNum 등을 추출하고 이를 POST data에 넣어 pdf 파일을 다운로드합니다. Post의 response 중 content-disposition에 들어 있는 파일 이름도 추출해서 이 이름 대로 pdf 파일을 저장합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import sys import openpyxl from urllib.request import urlopen import urllib from bs4 import BeautifulSoup import re import requests excel_file = openpyxl.load_workbook("데이터_국회의원 상임위 활동.xlsx") sheet = excel_file.active kinds = sheet['E'] # 회의종류 contents = sheet['F'] # 안건보기 for i in range(1, len(contents)): if kinds[i].value == "국회본회의": continue url = contents[i].value print(url) resp = urlopen(url) htm = str(resp.read().decode('euc-kr')) history = [] bs = BeautifulSoup(htm, "html.parser") for x in bs.findAll("a", onclick=True): if re.match('javascript:fn_fileDown', x['onclick']): args = x['onclick'].split() for a in args: nums = a.replace("javascript:fn_fileDown(", "").replace(");", "").split(",") if not nums in history: history.append(nums) payload = {"conferNum": nums[0].replace("'", ""), "fileId" : nums[1].replace("'", ""), "deviceGubun" : nums[2].replace("'", "")} r = requests.post("http://likms.assembly.go.kr/record/mhs-10-040-0040.do", data=payload) if (r.status_code == 200): d = r.headers['content-disposition'] flist = re.findall("filename=(.+)", d) fname = flist[0] # replace %xx escapes with their single-character equivalent fname_2 = urllib.parse.unquote(fname, encoding='utf-8').replace(";", "") print(fname_2) with open(fname_2, "wb") as f: f.write(r.content) |
댓글 없음:
댓글 쓰기