- 파이썬에서 다룰 수 있는
CSV
,웹
,XML
,JSON
네 가지 데이터 타입에 대해 공부CSV
파일 포맷은 어떠한 프로그래밍 언어든 데이터를 다루는 분야에서 가장 기본이 되는 타입형태엑셀의 텍스트 데이터 형태
와 유사하며, 매우 중요한 데이터 타입으로 파이썬으로핸들링
하는 것에 익숙해지는 것이 필요웹
은 우리 세상에서 가장 많은 정보를 제공하고 가장 많은 시간을 사용하고 있는 공간으로, 현재 매일 쓰고 있는 웹에서 가장 많은 정보를 얻고 있음.
- 이번 챕터에서 우리는 이 정보를
어떻게 자동으로 확보할 것인지
에 대해서 공부하고, 먼저 기본적인 웹을 표현하는 가장 기본적인 언어인HTML
에 대해서 공부- HTML은 웹에서 나타나는 정보의 표현 방법 중 가장 대표적인 방법으로 거의 모든 정보를 HTML 분석으로 얻을 수 있음.
- 다음으로 그 HTML을 분석하기 위해 대표적인 방법인
정규표현식(regex)
에 대해서 공부하며,
정규표현식은 텍스트 데이터 분석에 있어 가장 대표적인 분석 방법으로, HTML외에도 다양한 유형의 텍스트에서특정 정보
를 뽑아내는데 사용
- 마지막으로 데이터를 저장하는 다양한 포멧중 하나인
XML
(eXtensible Markup Languages)과JSON
(JavaScript Object Notation)에 대해서 공부.
- XML 프로그래밍 언어에서 데이터를 저장하고 불러오는 전통적인 파일포맷은 흔히
레거시 시스템
(오래전에 구축된 시스템)에서raw파일을 저장하는 대표적인 포맷
JSON
은 이와 달리모바일이 활발히 사용
되면서 사용되기 시작하는 저장 포맷으로 웹에서 많이 사용되는JavaScript의 문법을 활용하여 저장하는 포맷
- CSV,
필드
를쉼표(,)로 구분
한텍스트 파일
- 엑셀 양식의 데이터를 프로그램에 상관없이 쓰기 위한 데이터 형식이라고 생각하면 쉬움
탭(TSV)
,빈칸(SSV)
등으로구분
해서 만들기도 함- 통칭하여 character-separated values (CSV) 부름
- 엑셀에서는 “다른 이름 저장” 기능으로 사용 가능
quotechar
: ‘”
’ 기준 하나의 필드로 보겠다
- 위와 같이 오류가 있을 때, 읽을 때
cp949
로 읽겠다고 지정- 성남시 앞의 u는 유니코드의 약자로, ‘성남시’가 적혀져 있다면 append
- World Wide Web(WWW), 줄여서 웹이라고 부름
- 우리가 늘 쓰는 인터넷 공간의 정식 명칭
- 팀 버너스리에 의해 1989년 처음 제안되었으며, 원래는 물리학자들간 정보 교환을 위해 사용됨
- 데이터 송수신을 위한 HTTP 프로토콜 사용, 데이터를 표시하기 위해 HTML 형식을 사용
- 웹 상의 정보를 구조적으로 표현하기 위한 언어
- 제목, 단락, 링크 등 요소 표시를 위해
Tag <>
를 사용- 모든 요소들은
꺾쇠 괄호 안
에 둘러 쌓여 있음 Hello, World #제목 요소, 값은 Hello, World- 모든 HTML은
트리 모양의 포함관계
를 가짐- 일반적으로 웹 페이지의 HTML 소스파일은 컴퓨터가 다운로드 받은 후 웹 브라우저가 해석/표시
- 정보의 보고, 많은 데이터들이 웹을 통해 공유됨
환율정보 : https://finance.naver.com/
날씨정보 : http://goo.gl/nwi8WE
미국 특허정보 : http://bit.ly/3pxFkjb- HTML도 일종의 프로그램, 페이지 생성 규칙이 있음 :
규칙을 분석
하여데이터의 추출
이 가능- 추출된 데이터를 바탕으로 다양한 분석이 가능
- 정규 표현식,
regexp
또는regex
등으로 불림- 복잡한 문자열 패턴을 정의하는 문자 표현 공식
- 특정한 규칙을 가진 문자열의 집합을 추출
010-0000-0000 ^\d{3}\-\d{4}\-\d{4}$ IPV4 : 203.252.101.40 ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$
자막파일을 정규식으로 찾는 예시 (ctrl + h)
- 주민등록번호, 전화번호, 도서 ISBN 등 형식이 있는 문자열을 원본 문자열로부터 추출
- HTML 역시
tag
를 사용한 일정한 형식이 존재하여 정규식으로 추출이 용이- 관련자료: http://www.nextree.co.kr/p4327/
- 문법 자체는 매우 방대, 스스로 찾아서 하는 공부 필요
- 필요한 것들은 인터넷 검색을 통해 찾을 수 있음
- 기본적인 것을 공부 한 후 넓게 적용하는 것이 중요
- 정규식연습장(http://www.regexr.com/) 으로 이동
- 테스트하고 싶은 문서를 Text 란에 삽입
- 정규식을 사용해서 찾아보기
- 문자 클래스 [ ]: [ 와 ] 사이의 문자들과 매치라는 의미
예) [abc] ← 해당 글자가 a, b, c중 하나가 있다. “a”, “before”, “deep” , “dud”, “sunset”
“-“
를 사용 범위를 지정할 수 있음
예) [a-zA-z] – 알파벳 전체, [0-9] – 숫자 전체
- 정규식 표현을 위해 원래 의미 X,
다른 용도
로 사용되는 문자
. ^ $ * + ? { } [ ] \ | ( ).
은 전체를 다 잡아주고,*
은 반복할 수 있음- 줄바꿈 문자인 \n를 제외한 모든 문자와 매치 a[.]b
- 앞에 있는 글자를 반복해서 나올 수 있음
tomor*ow tomorrow tomoow tomorrrrow- 앞에 있는 글자를 최소 1회 이상 반복
- 정규식 표현을 위해 원래 의미 X, 다른 용도로 사용되는 문자
. ^ $ * + ? { } [ ] \ | ( )
{m.n}
- 반복 횟수를 지정 {1,} , {0,} {1,3}
203.252.101.40 [0-9]{1,3} \d{1,3}
?
- 반복 횟수가 1회 01[01]?-[0-9]{4}-[0-9]{4}
|
- or (0|1){3}^
- not
① 정규식 연습장(http://www.regexr.com/) 으로 이동
② 구글 USPTO Bulk Download 데이터 페이지 소스보기 클릭
③ 소스 전체 복사 후 정규식 연습장 페이지에 붙여넣기
④ 상단 Expression 부분을 수정해가며 “Zip”로 끝나는 파일명만 추출
⑤ Expression에 (http)(.+)(zip) 를 입력 →.+
는 중간에 무엇이 있어도 상관없다를 의미
http://www.google.com/googlebooks/uspto-patents-grants-text.html
- re 모듈을 import 하여 사용 :
import re
- 함수:
search
– 한 개만 찾기,findall
– 전체 찾기- 추출된 패턴은
tuple로 반환
됨- 연습 - 특정 페이지에서
ID만 추출
하기 https://bit.ly/3rxQFS4- ID 패턴: [영문대소문자|숫자] 여러 개, 별표로 끝남
"([A-Za-z0-9]+*****)“ 정규식
import re import urllib.request url = "[https://bit.ly/3rxQFS4](https://bit.ly/3rxQFS4)" html = urllib.request.urlopen(url) html_contents = str(html.read()) id_results = re.findall(r"([A-Za-z0-9]+\*\*\*)", html_contents) #findall 전체 찾기, 패턴대로 데이터 찾기 for result in id_results: print (result)
import urllib.request # urllib 모듈 호출 import re url = "http://www.google.com/googlebooks/uspto-patents-grants-text.html" #url 값 입력 html = urllib.request.urlopen(url) # url 열기 html_contents = str(html.read().decode("utf8")) # html 파일 읽고, 문자열로 변환 url_list = re.findall(r"(http)(.+)(zip)", html_contents) for url in url_list: print("".join(url)) # 출력된 Tuple 형태 데이터 str으로 join
① < dl class=“blind”>
< /dl>
(\<dl class=\"blind\">)([\s\S]+?)(\<\/dl>)
< dl class에서 시작해서 / 사이에 아무 글자나 있고 / < /dl> 로 끝내기
(→ 오류나서 "<" 뒤에 공백 넣음, 원래는 지워야 함)
② < dd>
< /dd> 정보를 추출하면 됨
(\< dd>)([\s\S]+?)(\< \/dd>)
< dd> 에서 시작해서 / 사이에 아무 글자나 있고 / < /dl> 로 끝내기
① 를 먼저 찾고 ① 안에 ②를 차례대로 찾으면 됨
(→ 오류나서 "<" 뒤에 공백 넣음, 원래는 지워야 함)
import urllib.request import re url = "http://finance.naver.com/item/main.nhn?code=005930" html = urllib.request.urlopen(url) html_contents = str(html.read().decode("ms949")) stock_results = re.findall("(\<dl class=\"blind\"\>)([\s\S]+?)(\<\/dl\>)", html_contents) samsung_stock = stock_results[0] # 두 개 tuple 값중 첫번째 패턴 samsung_index = samsung_stock[1] # 세 개의 tuple 값중 두 번째 값 # 하나의 괄호가 tuple index가 됨 index_list= re.findall("(\<dd\>)([\s\S]+?)(\<\/dd\>)", samsung_index) for index in index_list: print (index[1]) # 세 개의 tuple 값중 두 번째 값
- 데이터의 구조와 의미를 설명하는
TAG(MarkUp)
를 사용하여 표시하는 언어- TAG와 TAG사이에 값이 표시되고, 구조적인 정보를 표현할 수 있음
- HTML과 문법이 비슷, 대표적인 데이터 저장 방식
- 정보의 구조에 대한 정보인 스키마와 DTD 등으로 정보에 대한 정보(메타정보)가 표현되며, 용도에 따라 다양한 형태로 변경가능
- XML은 컴퓨터(예 : PC ↔ 스마트폰)간에 정보를 주고받기 매우 유용한 저장 방식으로 쓰임
<?xml version="1.0"?> <고양이> <이름>나비</이름> <품종>샴</품종> <나이>6</나이> <중성화>예</중성화> <발톱 제거>아니요</발톱 제거> <등록 번호>Izz138bod</등록 번호> <소유자>이강주</소유자> </고양이>
- XML도 HTML과 같이 구조적 markup 언어
- 정규표현식으로 Parsing이 가능함
- 그러나 좀 더 손쉬운 도구들이 개발되어 있음
- 가장 많이 쓰이는 parser인 beautifulsoup으로 파싱
- HTML, XML등 Markup 언어
Scraping
을 위한 대표적인 도구- https://www.crummy.com/software/BeautifulSoup/
- lxml 과 html5lib 과 같은
Parser를 사용
함- 속도는 상대적으로 느리나 간편히 사용할 수 있음
from bs4 import BeautifulSoup
- 모듈 호출
- 객체 생성
soup = BeautifulSoup(books_xml, "lxml")- Tag 찾는 함수 find_all 생성
soup.find_all("author")- find_all: 정규식과 마찬가지로 해당 패턴을 모두 반환
- find(‘invention-title’)
http://goo.gl/aeKMGS, http://goo.gl/lKhFzh 참고
Tag 네임 = title- get_text() : 반환된 패턴의 값 반환 (태그와 태그 사이)
- Adjustable shoulder device for hard upper torso suit
from bs4 import BeautifulSoup with open("books.xml", "r", encoding="utf8") as books_file: books_xml = books_file.read() # File을 String으로 읽어오기 soup = BeautifulSoup(books_xml, "lxml") # lxml Parser를 사용해서 데이터 분석 # author가 들어간 모든 element 추출 for book_info in soup.find_all("author"): print (book_info) print (book_info.get_text())
- 미국 특허청 (USPTO) 특허 데이터는 XML로 제공됨
- 해당 데이터중 등록번호 “08621662” 인 “Adjustable shoulder device for hard upper torso suit” 분석
참고: http://www.google.com/patents/US20120260387- XML 데이터를 Beautiful Soup을 통해 데이터 추출
import urllib.request from bs4 import BeautifulSoup with open("US08621662-20140107.XML","r", encoding="utf8") as patent_xml: xml = patent_xml.read() # File을 String으로 읽어오기 soup = BeautifulSoup(xml,"lxml") #lxml parser 호출 #invention-title tag 찾기 invention_title_tag = soup.find("invention-title") print (invention_title_tag.get_text())
- 특허의 출원번호, 출원일, 등록번호, 등록일, 상태, 특허명을 추출
<publication-reference> 등록 관련 정보 <document-id> <country>US</country> <doc-number>08621662</doc-number> 등록번호 <kind>B2</kind> 상태 <date>20140107</date> 등록일자 </document-id> </publication-reference> <application-reference appl-type="utility"> 출원 관련 정보 <document-id> <country>US</country> <doc-number>13175987</doc-number> 출원 번호 <date>20110705</date> 출원일 </document-id> </application-reference>
publication_reference_tag = soup.find("publication-reference") p_document_id_tag = publication_reference_tag.find("document-id") p_country = p_document_id_tag.find("country").get_text() p_doc_number = p_document_id_tag.find("doc-number").get_text() p_kind = p_document_id_tag.find("kind").get_text() p_date = p_document_id_tag.find("date").get_text() application_reference_tag = soup.find("application-reference") a_document_id_tag = publication_reference_tag.find("document-id") a_country = p_document_id_tag.find("country").get_text() a_doc_number = p_document_id_tag.find("doc-number").get_text() a_date = p_document_id_tag.find("date").get_text()
- ipa110106.xml 파일은 11년 첫째주에 나온 출원 특허를 모은 파일
- 개별 특허들을 나눠서 CSV 형태로 저장 하는 문제
- 개별 특허 시작은 <?xml version="1.0“ 시작함
- 분할된 특허 문서로 부터 특허의 등록번호, 등록일자, 출원 번호, 출원 일자, 상태, 특허 제목을 추출하여 CSV로 만들 것
- JavaScript Object Notation
- 원래 웹 언어인
Java Script의 데이터 객체 표현 방식
간결성
으로 기계/인간이 모두 이해하기 편함- 데이터 용량이 적고,
Code로의 전환이 쉬움
- 이로 인해
XML의 대체제
로 많이 활용되고 있음
- Python의 Dict Type과 유사,key:value 쌍으로 데이터 표시
- json 모듈을 사용하여 쉽게 parsing 및 저장 가능
- 데이터 저장 및 읽기는 dict type과 상호 호환 가능
- 웹에서 제공하는
API
는 대부분 정보 교환 시JSON 활용
- 페이스북, 트위터, Github 등 거의 모든 사이트
- 각 사이트 마다
Developer API의 활용법
을 찾아 사용
- JSON 파일의 구조를 확인 → reading → Dict Type처럼 처리
{"employees":[ {"firstName":"John","lastName":"Doe"}, {"firstName":"Anna","lastName":"Smith"}, {"firstName":"Peter","lastName":"Jones"} ]} import json with open("json_example.json","r", encoding="utf8") as f:contents = f.read() json_data = json.loads(contents) print(json_data["employees"])
- Dict Type으로 데이터 저장 → josn모듈로 Write