본문 바로가기
기타/파이썬

2. 판례 목록 수집 - 판례를 크롤링해보자

by 수완동날다람쥐 2021. 2. 28.

1. Intro

이전 포스팅에서 국가법령정보 Open API 사용법에 대해 간단히 알아보았다. 이제 제대로 판례 데이터를 수집해보고자 한다.

판례 데이터 수집은 2단계로 이루어진다.

  1. 판례 목록 데이터 수집

  2. 판례 본문 데이터 수집

굳이 판례 목록 데이터를 수집해주는 이유는, 판례 본문 데이터 조회때 필요하기 때문이다. 판례 본문을 조회할 때, 판례 일련번호 정보를 통해 조회하는데, 판례 일련번호 정보는 판례 목록 데이터에 존재한다.

이번 포스트에서는 판례 목록을 수집해 csv로 저장하도록 하겠다.

 

2. 수집

순서는 간단하다.

  1. url을 통해 XML 데이터를 받아온다
  2. 판례 관련 정보들만 추출한다
  3. 추출한 데이터들을 각 항목별로 정리한다
  4. DataFrame으로 만들어 csv 파일로 저장한다
import pandas as pd
import xml.etree.ElementTree as ET
from urllib.request import urlopen
from tqdm import trange

필요한 라이브러리를 import한다.

 

url = "https://www.law.go.kr/DRF/lawSearch.do?OC={아이디}&target=prec&type=XML"
response = urlopen(url).read()
xtree = ET.fromstring(response)

API 호출을 위한 URL을 선언하고, urllib.request.urlopen 을 통해 데이터를 받아온다.

 

  • PrecSearch
    • target
    • 키워드
    • section
    • totalCnt
    • page
    • prec
      • 판례일련번호
      • 사건명
      • 사건번호
      • 법원명
      • 사건종류명
      • 사건종류코드
      • 판결유형
      • 선고
      • 판례상세링크
    • prec
      • ...

위 URL을 호출하면 위와 같은 형태의 데이터가 불러진다. 

 

totalCnt = int(xtree.find('totalCnt').text)

각 페이지별로 20개씩 판례 목록이 조회된다. 반복횟수를 정해주기 위해 판례 목록 전체 갯수를 미리 가져온다.

 

page = 1
rows = []
for i in trange(int(totalCnt / 20)):
    try:
        items = xtree[5:]
    except:
        break
        
    for node in items:
        판례일련번호 = node.find('판례일련번호').text
        사건명 = node.find('사건명').text
        사건번호 = node.find('사건번호').text
        선고일자 = node.find('선고일자').text
        법원명 = node.find('법원명').text
        사건종류명 = node.find('사건종류명').text
        사건종류코드 = node.find('사건종류코드').text
        판결유형 = node.find('판결유형').text
        선고 = node.find('선고').text
        판례상세링크 = node.find('판례상세링크').text

        rows.append({'판례일련번호': 판례일련번호,
                    '사건명': 사건명,
                    '사건번호': 사건번호,
                    '선고일자': 선고일자,
                    '법원명': 법원명,
                    '사건종류명': 사건종류명,
                    '사건종류코드': 사건종류코드,
                    '판결유형': 판결유형,
                    '선고': 선고,
                    '판례상세링크': 판례상세링크})
    cnt += 1
    url = "https://www.law.go.kr/DRF/lawSearch.do?OC=spliter&target=prec&type=XML&page={}".format(page)
    response = urlopen(url).read()
    xtree = ET.fromstring(response)

한 페이지당 20개씩 판례 정보가 담겨있기 때문에, totalCnt / 20 개의 페이지를 돌아다니며 판례 목록 정보를 수집해온다. target, 키워드 등은 필요없는 정보이기때문에 과감히 무시하고, 판례 정보만을 받아온다(prec). 각 정보들을 dictionary 형태로 저장해주고, rows 리스트에 집어넣어준다. 해당 페이지 내 모든 판례 목록 정보를 불러왔으면 다음 페이지를 호출하면서 Loop를 돈다.

오늘 기준 약 80,000여 개의 판례 데이터가 존재한다.

 

cases = pd.DataFrame(rows)
cases.to_csv('./cases.csv', index=False)

dictionary들이 들어있는 리스트를 DataFrame으로 만들어주고 이 df를 csv파일로 변환해주면 끝이다.

 

약 35분이 소요되었다.

 

잘 된것같다!

3. 전체 코드

import pandas as pd
import xml.etree.ElementTree as ET
from urllib.request import urlopen
from tqdm import trange

url = "https://www.law.go.kr/DRF/lawSearch.do?OC={아이디}&target=prec&type=XML"
response = urlopen(url).read()
xtree = ET.fromstring(response)

totalCnt = int(xtree.find('totalCnt').text)

page = 1
rows = []
for i in trange(int(totalCnt / 20)):
    try:
        items = xtree[5:]
    except:
        break
        
    for node in items:
        판례일련번호 = node.find('판례일련번호').text
        사건명 = node.find('사건명').text
        사건번호 = node.find('사건번호').text
        선고일자 = node.find('선고일자').text
        법원명 = node.find('법원명').text
        사건종류명 = node.find('사건종류명').text
        사건종류코드 = node.find('사건종류코드').text
        판결유형 = node.find('판결유형').text
        선고 = node.find('선고').text
        판례상세링크 = node.find('판례상세링크').text

        rows.append({'판례일련번호': 판례일련번호,
                    '사건명': 사건명,
                    '사건번호': 사건번호,
                    '선고일자': 선고일자,
                    '법원명': 법원명,
                    '사건종류명': 사건종류명,
                    '사건종류코드': 사건종류코드,
                    '판결유형': 판결유형,
                    '선고': 선고,
                    '판례상세링크': 판례상세링크})
    page += 1
    url = "https://www.law.go.kr/DRF/lawSearch.do?OC={아이디}&target=prec&type=XML&page={}".format(page)
    response = urlopen(url).read()
    xtree = ET.fromstring(response)
cases = pd.DataFrame(rows)
cases.to_csv('./cases.csv', index=False)

댓글