Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
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
Archives
Today
Total
관리 메뉴

에코프로.AI

[Python] Requests 라이브러리 소개 및 활용(Feat. xml) 본문

AI Tutorial

[Python] Requests 라이브러리 소개 및 활용(Feat. xml)

AI_HitchHiker 2024. 8. 20. 19:20

https://levelup.gitconnected.com/an-introduction-to-python-requests-simplifying-web-communication-311851f7405e

  • Requests 라이브러리
    • 파이썬에서  HTTP요청을 보내기 위해 널리 사용되는 라이브러리
    • 간단하고 직관적인 인터페이스 제공하여, GET, POST, PUT, DELETE  등의 HTTP메소드 사용이 용이함.
    • 주요 특징
      • 간단한 HTTP요청/응답 처리
      • 다양한 HTTP 메소드 지원 (GET / POST / PUT / DELETE 등)
      • 요청 매개변수와 헤더 설정
      • JSON 데이터 자동 파싱
      • 타임아웃 및 예외처리 기능
    • 라이브러리 설치
pip install requests
  • Requests 기본 사용법
    • GET 요청 보내기
      • 서버에 데이터를 요청할 때, get() 함수 사용

공공데이터 API를 통한 xml 데이터 처리

  • requests 라이브러리 사용 선언
import requests

공공데이터 실습

  • 공공데이터 포털
  • "식품의약품 안전처_식품 영양성분 정보"
    • 사이트 접속 후, "활용신청"을 눌러서 API KEY를 받는다.

 

 

  • "바나나칩"의 식품정보 가져오기
import requests
import pandas as pd
from lxml import etree

# 일반 인증키 (Decoding) 사용
apikey = '공공데이터 포털에서 "활용신청"을 통해서 받은 API KEY'

url = 'http://apis.data.go.kr/1471000/FoodNtrIrdntInfoService1/getFoodNtrItdntList1'

# 새우깡
#  (식품이름, 열량, 1회제공량, 구축년도) DataFrame 형태로 반환
params ={'serviceKey' : apikey,
         'desc_kor' : '바나나칩',
         'pageNo' : '1',
         'numOfRows' : '3',
         'bgn_year' : '2017',
         'animal_plant' : '(유)돌코리아',
         'type' : 'xml' }

# 데이터 가져오기
response = requests.get(url, params=params)

if response.status_code == 200:
    # result = response.json()
    # items = result['body']['items']
    # data = []
    # for item in items:
    #     # 'DESC_KOR', 'NUTR_CONT1', 'SERVING_WT', 'BGN_YEAR'
    #     data.append([item['DESC_KOR'], item['NUTR_CONT1'], item['SERVING_WT'], item['BGN_YEAR']])

    # df = pd.DataFrame(data, columns=['식품이름', '1회 제공량', '열량', '조사년도'])
    # print(df)

    print(response.encoding)            # (ISO-8859-1) 수신된 데이터의 인코딩 방법
    print(response.apparent_encoding)   # (UTF-8-SIG) 추정 인코딩 방법

    print(type(response.content))       # <class 'bytes'>
    print(response.content)
    print(type(response.text))          # <class 'str'>
    print(response.text)

    root = etree.fromstring(response.content)
else:
    print('실패 : ', response.status_code)

 

xml 데이터 파싱관련

items = root.findall('.//item')

lst = []

for i, item in enumerate(items):
    # print(f'{i}\r\n')
    # print(item.tag, item.text)

    # lst.append([item.findtext('.//DESC_KOR'), item.findtext('.//NUTR_CONT1')])
    lst.append([item.find('.//DESC_KOR').text, item.find('.//NUTR_CONT1').text])

print('lst : \r\n', lst)

df = pd.DataFrame(lst, columns = ['식품이름', '1회 제공량'])
df

 

API 호출함수 구현

def Call_API():
    import requests
    import pandas as pd
    import xml.etree.ElementTree as ET
    from lxml import etree

    _desc_kor = str(input('식품이름을 입력해주세요=>'))
    print(f'{_desc_kor}를 입력하셨습니다')

    # 일반 인증키 (Decoding) 사용
    apikey = '공공데이터 포털에서 "활용신청"을 통해서 받은 API KEY'

    url = 'http://apis.data.go.kr/1471000/FoodNtrIrdntInfoService1/getFoodNtrItdntList1'

    # 새우깡
    #  (식품이름, 열량, 1회제공량, 구축년도) DataFrame 형태로 반환
    params ={'serviceKey' : apikey,
             'desc_kor' : _desc_kor,
             'type' : 'xml' }

    # 데이터 가져오기
    response = requests.get(url, params=params)

    if response.status_code == 200:
        # bytes => str(문자열) 로 변환
        root = etree.fromstring(response.content)

        # 엘리먼트를 바이트 문자열로 변환한 후, 문자열로 변환
        str_enc = ET.tostring(root, encoding='utf-8').decode('utf-8')
        # print(str_enc)

        # <header>
        # <body>
        # <items>
        #   <item>
        #       <DESC_KOR>
        #       <NUTR_CONT1>
        #       ...
        #   <item>
        #       <DESC_KOR>
        #       <NUTR_CONT1>
        #       ...
        if root.findtext('.//totalCount') != '0':
            items = root.findall('.//item')             # item 엘리먼트 전체 찾기

            lst = []

            for i, item in enumerate(items):
                # print(f'{i}\r\n')
                # print(item.tag, item.text)

                lst.append([item.findtext('.//DESC_KOR'), item.findtext('.//NUTR_CONT1')])
                # lst.append([item.find('.//DESC_KOR').text, item.find('.//NUTR_CONT1').text])

            print('lst : \r\n', lst)
            df = pd.DataFrame(lst, columns = ['식품이름', '1회 제공량']).sort_values(by='1회 제공량', ascending=False)

            return df
        else:
            return _desc_kor + '을 조회하지 못했습니다.'
            #return []
    else:
        return '실패 : ', response.status_code

 

함수호출

 

 

결과값


jtbc 뉴스 크롤링

import requests
from lxml import etree
import xml.etree.ElementTree as ET

url = 'https://fs.jtbc.co.kr/RSS/culture.xml'
response = requests.get(url)

if response.status_code == 200:
    print(response.encoding)            # (ISO-8859-1) 수신된 데이터의 인코딩 방법
    print(response.apparent_encoding)   # (UTF-8-SIG) 추정 인코딩 방법

    print(type(response.content))       # <class 'bytes'>
    print(response.content)
    print(type(response.text))          # <class 'str'>
    print(response.text)

    #print(etree.fromstring(response.content))
    root = etree.fromstring(response.content)
else:
    print(response.status_code)

 

# request 정보
print('response.request.method : ', response.request.method)
print('response.request.url : ', response.request.url)
print('response.request.headers : ', response.request.headers)
print('response.request.body : ', response.request.body)

 

# response 정보
print('response.status_code : ', response.status_code)
print('response.headers : ', response.headers)
print('response.text : ', response.text)

 

print(root)
print('root type : ', type(root))   # <class 'lxml.etree._Element'>

 

import pandas as pd

items = root.findall('.//item')

lst = []

for i, item in enumerate(items):
    # print(f'{i}\r\n')
    # print(item.tag, item.text)

    # lst.append([item.findtext('.//title'), item.findtext('.//link')])
    lst.append([item.find('.//title').text[:30], item.find('.//link').text[:30]])

print('lst : \r\n', lst)

df = pd.DataFrame(lst, columns = ['제목', '링크'])
df