Python – XML
XML 이란?
- XML은 eXtensible Markup Language 의 약어이다.
- W3C에서 개발 다른 특수한 목적을 갖는 마크업 언어를 만드는데 사용하도록 권장
- XML은 확장 가능한 마크업 언어를 나타낸다.
- XML은 HTML과 유사한 마크업 언어이다.
- XML은 데이터를 저장하고 전송하도록 설계되었습니다.
- XML 이ㅃ게 보기 : http://xmlgrid.net/
XML Example
<employees>
<employee>
<firstName>Joo</firstName>
<lastName>Duu</lastName>
</employee>
<employee>
<firstName>Koo</firstName>
<lastName>Kuu</lastName>
</employee>
<employee>
<firstName>Loo</firstName>
<lastName>Luu</lastName>
</employee>
</employees>
XML은 단지 태그 과 값을 이루어진 정보이다
XML 과 HMTL 과의 차이
- XML은 designed to carry data – with focus on what data is (데이터 자체 관점)
- HTML 은 designed to display data – with focus on how data looks(데이터가 보여질 모양 관점)
- XML은 태그가 HTML 처럼 미리 정의 되어 있지 않다
XML Tree
- XML 문서는
root
에서 시작해서 ‘leaves’ 가지를 가지는 트리(tree) 구조 이다
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
XML Tree Structure
XML Tree Structure
- XML문서는 요소들의 tree로 구성되어 있다.
- XML트리는 루트 요소(root element)에서 시작 자식 요소들(child elements)로 가지를 친다
- 모든 요소들은 자식 요소들을 가질 수 있다.
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
XML 문서는 다음과 같이 자신에 대한 정보(The XML prolog)를 선언 할 수 있다
<?xml version="1.0" encoding="UTF-8"?>
XML 문법 규칙
- XML 문서는은 하나이 Root Element를 가져야 한다
- The XML prolog 는 맨 처음 문장에 와야 한다.
- 모든 XML 요소는 닫는 태그(Closing Tag)를 가져야 한다.
- XML 태그는 대소문자를 구분한다.
- XML 요소는 정상적으로 중첩되어야 한다.
<b><i>This text is bold and italic</b></i> (X)
<b><i>This text is bold and italic</i></b> (O)
- XML 속성 값은 반드시 쌍따움표 안데 들어가야 한다.
<note date=12/11/2007>Text</note> (X)
<note date="12/11/2007">Text</note> (O)
- XML 주석
<!-- This is a comment -->
- 구문 규칙을 준수하는 XML문서를 Well Formed XML 라 한다.
XML 요소 (XML Element)
XML 요소는 다음을 포함한다
– text
– 속성 attributes
– 다른 요소 other elements
<bookstore>
<book category="children">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
빈 XML 요소 (Empty XML Elements)
<element></element> (O)
<element /> (O)
XML 요소 이름 규칙 (XML Naming Rule)
- 대소문자를 가린다.
- 첫 글자는 문자여야 한다.
- 공백이 들어가면 안된다.
Naming Styles (참고)
Style | Example | Description |
---|---|---|
Lower case | <firstname> | All letters lower case |
Upper case | <FIRSTNAME> | All letters upper case |
Underscore | <first_name> | Underscore separates words |
Pascal case | <FirstName> | Uppercase first letter in each word |
Camel case | <firstName> | Uppercase first letter in each word except the first |
XML (속성) XML Attributes
- xml 속성은 특별한 요소와 관련된 데이터를 포함하기 위해 사용한다.
- xml 속성 값은 항상
""
또는''
안에 넣어야 한다.
<person gender="female">
<person gender='female'>
<gangster name='George "Shotgun" Ziegler'>
<gangster name="George "Shotgun" Ziegler">
XML Elements vs. Attributes
Attributes
<note date="2008-01-10">
<to>Tove</to>
<from>Jani</from>
</note>
Elements
<note>
<date>2008-01-10</date>
<to>Tove</to>
<from>Jani</from>
</note>
<note>
<date>
<year>2008</year>
<month>01</month>
<day>10</day>
</date>
<to>Tove</to>
<from>Jani</from>
</note>
요소를 사용하거나 속성을 사용하는데 특별한 규칙은 없다.
하지만
- 아래와 같이 속성을 사용하지는 말자!!
- 구조화 된 문서(트리구조)등을 사용 할 수 없다
<note day="10" month="01" year="2008"
to="Tove" from="Jani" heading="Reminder"
body="Don't forget me this weekend!">
</note>
하지만
- 특정 요소를 구분할 ID references를 지정시는 사용하자
<messages>
<note id="501">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note id="502">
<to>Jani</to>
<from>Tove</from>
<heading>Re: Reminder</heading>
<body>I will not</body>
</note>
</messages>
XML Text 를 JavaScript Object로 변환 하기
JSON Text를 자바 스크립트로 변환하기 위해 DOMParser() 를 사용한다.
파일명 : xmltest.html
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var parser, xmlDoc;
var text = "<bookstore><book>" +
"<title>Everyday Italian</title>" +
"<author>Giada De Laurentiis</author>" +
"<year>2005</year>" +
"</book></bookstore>";
if (window.DOMParser) {
// code for modern browser
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
} else {
// code for old IE browsers
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(text);
}
var title_value = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
//alert(title_value);
document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
</script>
</body>
</html>
Pyhton XML
xml.etree.ElementTree module 사용
from urllib.request import urlopen
from xml.etree.ElementTree import parse
# Download the RSS feed and parse it
u = urlopen('http://planet.python.org/rss20.xml')
doc = parse(u)
# Extract and output tags of interest
for item in doc.iterfind('channel/item'):
title = item.findtext('title')
date = item.findtext('pubDate')
link = item.findtext('link')
print(title)
print(date)
print(link)
print()
네이버 OPEN API 로 책 검색기 만들기 – XML
사이트 주소 : https://developers.naver.com
오픈API 이용신청
로그인 > Documents > API 공통 가이드 > 오픈API 이용신청
오픈API 사용방법
https://developers.naver.com/docs/search/book/
파일명 : naver_book_search_xml.py
import urllib.request
from xml.etree.ElementTree import parse
client_id = "****" # 애플리케이션 등록시 발급 받은 값 입력
client_secret = "****" # 애플리케이션 등록시 발급 받은 값 입력
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/book.xml?query=" + encText # xml 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id",client_id)
request.add_header("X-Naver-Client-Secret",client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if(rescode==200):
resp = parse(response)
for item in resp.iterfind('channel/item'):
title = item.findtext('title')
date = item.findtext('price')
link = item.findtext('discount')
print(title)
print(date)
print(link)
print()
else:
print("Error Code:" + rescode)
urllib 라이브러리 import
- https://docs.python.org/3/library/urllib.html (파이썬 표준 라이브러리)
-
http 프로토콜 서버에 요청/응답을 할 수 있도록 도와주 라이브러리
-
request는 클라이언트의 요청을 처리
- response는 서버의 응답을 처리한다.
- parse는 URL을 분석한다.
request url 생성
-
urllib.parse.quote를 통해서 비 ASCII 문자를 UTF-8 형식으로 URL 인코딩
-
문자열은 유니코드로 구성되어있고, 바이트는 0~255사이 코드의 열
foo = '1234abcd' # 문자열(유니코드) koo = b'1234abcd' # 바이트 상수(b로 시작) foo_enc = foo.encode() # 문자열(유니코드) -> 바이트 koo_dec = koo.decode() # 바이트 -> 문자열(유니코드, utf-8) print(type(foo)) # <class 'str'> print(type(koo)) # <class 'bytes'> print(type(foo_enc)) # <class 'bytes'> print(type(koo_dec)) # <class 'str'>
Request 객체 생성 및 header 추가
- urllib.request.Request 클래스는 URL 요청과 관련된 클래
- http 통신 시 header 값을 설정하거나, HTTP request method(PUT,UPDATE,DELETE..) 등을 설정
- Request 클래스의 add_header메소드로 헤더 정보를 추가
urlopen(요청) 및 response (응답)
- urllib.request.urlopen 메소드에 매개변수로 url string 혹은 request 객체를 전달
- header 정보를 포함시 request 객체로 전달
- urlopen 메소드는 http.client.HTTPResponse 객체 리턴
- HTTPResponse 객체 메소드
-
geturl() : source 의 url을 반환(redirect 여부를 확인)
- getcode() : response의 HTTP status code 를 리턴
오류코드확인 : https://developers.naver.com/docs/search/blog/
response 객체
- status code가 200인 경우 (정상 호출)
import urllib.request
from xml.etree.ElementTree import parse
def py_xml_proc(data):
for item in data.iterfind('channel/item'):
book_title = item.findtext('title')
book_price = item.findtext('price')
book_discount = item.findtext('discount')
book_info = "제목 : {0} / 가격 : {1} / 할인가 : {2}".format(book_title, book_price, book_discount)
print(book_info)
def naver_search_xml(search_word):
client_id = "*****" # 애플리케이션 등록시 발급 받은 값 입력
client_secret = "*****" # 애플리케이션 등록시 발급 받은 값 입력
search_word_enc = urllib.parse.quote(search_word)
url = "https://openapi.naver.com/v1/search/book.xml?query=" + search_word_enc + "&display=" + book_num + "&sort=count" # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id", client_id)
request.add_header("X-Naver-Client-Secret", client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if (rescode == 200):
xml_data = parse(response)
py_xml_proc(xml_data)
else:
print("Error Code:" + rescode)
book_num = "3"
#book_name = "파이썬"
book_name = input("Enter Book Name : ")
naver_search_xml(book_name)
네이버 OPEN API 책 검색기 최종
import urllib.request
from xml.etree.ElementTree import parse
def py_xml_proc(data):
for item in data.iterfind('channel/item'):
book_title = item.findtext('title')
book_price = item.findtext('price')
book_discount = item.findtext('discount')
book_info = "제목 : {0} / 가격 : {1} / 할인가 : {2}".format(book_title, book_price, book_discount)
print(book_info)
def naver_search_xml(search_word):
client_id = "*****" # 애플리케이션 등록시 발급 받은 값 입력
client_secret = "*****" # 애플리케이션 등록시 발급 받은 값 입력
search_word_enc = urllib.parse.quote(search_word)
url = "https://openapi.naver.com/v1/search/book.xml?query=" + search_word_enc + "&display=" + book_num + "&sort=count" # XML 결과
request = urllib.request.Request(url)
request.add_header("X-Naver-Client-Id", client_id)
request.add_header("X-Naver-Client-Secret", client_secret)
response = urllib.request.urlopen(request)
rescode = response.getcode()
if (rescode == 200):
xml_data = parse(response)
py_xml_proc(xml_data)
else:
print("Error Code:" + rescode)
book_num = "3"
prompt = """
... 1. Book Search
... 2. Blog Serach
... 3. News Serch
... 4. Quit
...
... Enter number: """
number = 0
while number != 4:
print(prompt)
number = int(input())
if number == 1:
book_name = input("Enter Book Name : ")
naver_search_xml(book_name)