colab 실습 링크 : https://colab.research.google.com/drive/1qjMVDgpZCX50Ej8fOqaKbFcLSdYpfJK2?usp=sharing
모든 실행 결과는 colab에서 확인 할 수 있습니다.
import json
d = {"name": "혼자 공부하는 데이터 분석"}
d_str = json.dumps(d, ensure_ascii=False) # ensure_ascii를 비활성화 하여 한글이 16진수로 변환되지 않도록 설정
d2 = json.loads(d_str)
print(d2['name'])
d3 = json.loads('{"name": "혼자 공부하는 데이터 분석", "author": ["박해선", "홍길동"], "year": 2022}')
d4_str = """
[
{"name": "혼자 공부하는 데이터 분석", "author": "박해선", "year": 2022},
{"name": "혼자 공부하는 머신러닝+딥러닝", "author": "박해선", "year": 2020}
]
"""
d4 = json.loads(d4_str)
""" ~ """을 통해 긴 문자열을 줄바꿈하여 입력 가능
import pandas as pd
pd.read_json(d4_str)
x_str = """
<book>
<name>혼자 공부하는 데이터 분석</name>
<author>박해선</author>
<year>2022</year>
</book>
"""
import xml.etree.ElementTree as et
book = et.fromstring(x_str)
book_childs = list(book)
print(book_childs)
[<Element 'name' at 0x7f77e8598b80>, <Element 'author' at 0x7f77e85d4720>, <Element 'year' at 0x7f77e85d4630>]
name, author, year = book_childs
print(name.text)
혼자 공부하는 데이터 분석
name = book.findtext('name')
author = book.findtext('author')
year = book.findtext('year')
print(name)
혼자 공부하는 데이터 분석
x2_str = """
<books>
<book>
<name>혼자 공부하는 데이터 분석</name>
<author>박해선</author>
<year>2022</year>
</book>
<book>
<name>혼자 공부하는 머신러닝+딥러닝</name>
<author>박해선</author>
<year>2022</year>
</book>
</books>
"""
books = et.fromstring(x2_str)
for book in books.findall('book'):
name = book.findtext('name')
author = book.findtext('author')
year = book.findtext('year')
print (name)
print(author)
print(year)
혼자 공부하는 데이터 분석
박해선
2022
혼자 공부하는 머신러닝+딥러닝
박해선
2022
pd.read_xml(x2_str)
도서관 정보나루 공공데이터 웹 API활용.
URL : "http://data4library.kr/api/loanItemSrch?authKey=${API_KEY}&format=json&startDt=2021-04-01&endDt=2021-04-30&age=20"
import requests
url = "http://data4library.kr/api/loanItemSrch?authKey=${API_KEY}&format=json&startDt=2021-04-01&endDt=2021-04-30&age=20"
#response 데이터를 JSON으로 가져오기
r = requests.get(url)
data = r.json
#response 중 필요한 데이터만 가져오기 (이 경우엔 책 정보가 docs 내부에 들어있음.)
books = []
for d in data['response']['docs']:
books.append(d['doc'])
#pandas DataFrame으로 변환하기
books_df = pd.DataFrame(books)
#JSON 파일로 저장하기
books_df.to_json('20s_best_book.json', force_ascii=False)
! 도서별 쪽수가 필요하지만 관련 API가 없다면? Yes24 등 서점 사이트에서 제공하는 쪽수 정보를 스크래핑으로 얻을 수 있다.
books_df = pd.read_json('20s_best_book.json')
books = books_df[['no', 'ranking', 'bookname', 'authors', 'publisher', 'publication_year', 'isbn13']]
books_df.iloc[[0, 1], [2, 3]]
books = books_df.loc[:, 'no':'isbn13']
books_df.loc[::2, 'no':'isbn13'].head()
isbn = ${찾고싶은 책의 ISBN}
url = 'http://www.yes24.com/Product/Search?domain=BOOK&query={}'
r = requests.get(url.format(isbn))
from bs4 import BeautifulSoup
soup = BeautifulSoup(r.text, 'html.parser')
# HTML : <a class="gd_name" href="/Product/Goods/74261416" onclick="setSCode('101_005_003_001');setGoodsClickExtraCodeHub('032', '9791190090018', '74261416', '0');">우리가 빛의 속도로 갈 수 없다면</a>
prd_link = soup.find('a', attrs={'class':'gd_name'})
url = 'http://www.yes24.com'+prd_link['href']
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
prd_detail = soup.find('div', attrs={'id':'infoset_specific'})
prd_tr_list = prd_detail.find_all('tr')
for tr in prd_tr_list:
if tr.find('th').get_text() == '쪽수, 무게, 크기':
page_td = tr.find('td').get_text()
break
print(page_td.split()[0])
330쪽
def get_page_cnt(isbn):
url = 'http://www.yes24.com/Product/Search?domain=BOOK&query={}'
r = requests.get(url.format(isbn))
soup = BeautifulSoup(r.text, 'html.parser')
prd_info = soup.find('a', attrs={'class':'gd_name'})
url = 'http://www.yes24.com' + prd_info['href']
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
prd_detail = soup.find('div', attrs={'id':'infoset_specific'})
prd_tr_list = prd_detail.find_all('tr')
for tr in prd_tr_list:
if tr.find('th').get_text() == '쪽수, 무게, 크기':
return tr.find('td').get_text().split()[0]
return ''
get_page_cnt(9791190090018)
'330쪽'
def get_page_cnt2(row):
isbn = row['isbn13']
return get_page_cnt(isbn)
top10_books = books.head(10)
page_count = top10_books.apply(get_page_cnt2, axis=1)
apply(함수, axis)
함수 : DataFrame의 각 행이나 열에 적용시킬 함수
axis 0 : 기본값, 각 열에 적용
axis 1 : 각 행에 적용
page_count = top10_books.apply(lambda row: get_page_cnt(row['isbn13']), axis=1)
page_count.name = 'page_count' # 열 이름 지정
top10_with_page_count = pd.merge(top10_books, page_count, left_index=True, right_index=True) # index를 기준으로 합치기
top10_with_page_count
how='left' == left join
how='right' == right join
how='outer' == outer join ...
웹 크롤링으로 접하고 있었던 웹 스크래핑을 실제로 경험할 수 있는 유익한 시간이었다. 개발 작업을 하거나, 개인적인 호기심을 채우기 위해서도 활용 할 수 있을 것 같다.
스크래핑 작업 시 예제처럼 10개 책의 쪽수를 가져오는 것만 해도 생각보다 부하가 걸리는 것을 확인할 수 있었다. 웹 개발을 하면서 이런 스크래핑에 의한 부하에 대해서도 고려하면서 개발해야 할 것 같다.(robots.txt 파일을 작성하고 활용하는 방법에 대해서도 알아두어야 할 것 같다.)