오늘 시간에는 가장 보편적으로 사용되는 리스트(list) 자료구조에 대해 설명을 드리겠습니다.
리스트는 간단하게 항목들의 모음집이라고 생각하시면 됩니다.
1. 리스트 생성
파이썬에서 리스트는 아래 소스코드와 같이 생성할 수 있습니다. 빈 리스트를 생성할 때 []에 아무값도 넣지 않으시면 됩니다. 그리고 리스트에 들어가는 값들을 각각의 요소(element)라고 부릅니다.
리스트의 각 요소는 서로 다른 자료형(int, string 등)으로 이루어질 수 있습니다.
a = [] # 빈 리스트
b = [1,2,3,4]
c = ["a", "b", "c"]
d = [1, 2, "a", "b"]
2. 리스트의 요소 출력
리스트를 생성하였다면 그 안의 값을 출력해 볼 수도 있습니다. 아래 코드처럼 리스트 자료구조인 변수 b를 출려하면 b에 포함된 모든 요소를 출력합니다.
여기서 조심해야 할 것은 순서를 가리키는 인덱스(index) 번호입니다. 우리는 일반적으로 시작을 1로 합니다. 하지만 컴퓨터에서의 시작은 언제나 0으로부터 시작합니다.
b = [1,2,3,4]
print(b) # 리스트의 모든 요소를 출력
print(b[0]) # 첫번째 요소를 출력
print(b[3]) # 네번째 요소를 출력
print(b[-1]) # 마지막 요소를 출력
###출력 결과###
[1, 2, 3, 4]
1
4
4
또 리스트에서의 요소는 순서가 정해져 있기 때문에 문자열처럼 슬라이싱(slicing)이 가능합니다. 아래 예시 결과를 보시면 슬라이싱할 때 다음과 같은 규칙을 가지고 있습니다.
예를 들어, [0:5]라고 한다면 0 즉 첫번째 값부터 (5-1)번째 까지의 값을 출력합니다.
그리고 [5 : ]에서 끝 인덱스가 없을 경우에는 모든 값을 출력한다는 의미입니다.
b = [1,2,3,4,5,6,7,8,9,10]
print(b[0:5]) # 0~4번째까지의 값을 출력
print(b[5:]) # 5번째부터 이후의 값을 출력
print(b[2:-2]) # 2번째부터 마지막 3번째 값을 출력
###출력 결과###
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[3, 4, 5, 6, 7, 8]
b = [1,2,3,4]
b.insert(0,100) # 첫번째 인자는 인덱스 번호, 두번째 인자는 삽입할 값
print(b)
###출력 결과###
[100, 1, 2, 3, 4]
remove()
b = [1,2,3,4]
b.remove(4) # 삭제할 값을 입력
print(b)
###출력 결과###
[1, 2, 3]
pop()
b = [1,2,3,4]
b.pop()
print(b)
###출력 결과###
[1, 2, 3]
index()
b = [1,2,3,4]
print(b.index(4)) # 요소의 값을 입력
print(b.index(5)) # 리스트에 5라는 요소가 없기 때문에 에러
###출력 결과###
3
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-26-fd31e41e0b25> in <module>
2 print(b.index(4))
3
----> 4 print(b.index(5))
ValueError: 5 is not in list
count()
b = [1,2,3,4,1,2,1,3,1,2]
print(b.count(1)) # 요소의 값을 입력
###출력 결과###
4
sort()
b = [1,2,3,4,1,2,1,3,1,2]
b.sort() # 오름차순으로 정렬, 인자가 없을 때 초기값은 오름차순
b
###출력 결과###
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4]
b = [1,2,3,4,1,2,1,3,1,2]
b.sort(reverse = True) # 내림차순으로 정렬
b
###출력 결과###
[4, 3, 3, 2, 2, 2, 1, 1, 1, 1]
여기까지 파이썬 리스트 자료구조에 대해 알아보았습니다. 다음 시간에는 튜플(tuple) 자료구조에 대해 알아보겠습니다.
from bs4 import BeautifulSoup
import urllib
# 검색할 사이트
root_url = "http://www.yes24.com/24/category/bestseller?CategoryNumber=117&sumgb=06"
# HTML 헤더
head = {'User-Agent' : "Magic Browser"}
# 요청보내기
request = urllib.request.Request(root_url, headers = head)
# 응답 받기
response = urllib.request.urlopen(request)
# 응답을 Beautifulsoup 패키징화하기
soup = BeautifulSoup(response.read().decode('euc-kr','replace'))
그리고 디렉토리(directory)를 만들어 줍니다. 이걸 만드는 목적은 우리가 다운로드할 이미지를 저장하기 위해서 입니다.
import os # 시스템 함수
# 이미지를 저장할 디렉토리
directory_path = "book_image"
# 디렉토리가 존재하지 않을 시 자동 생성
if not os.path.exists(directory_path):
os.makedirs(directory_path)
아래 소스코드는 도서 이미지를 다운로드하는 소스코드입니다.
# 도서 이미지를 포함하고 있는 태그
contents = soup.find_all('div', {'class':'goodsImgW'})
for content in contents:
# 각 도서를 의미하는 <a> 태그
book_image = content.find_all('a')
# 태그안에 있는 모든 이미지
for i in range(0, len(book_image)):
if i % 2 ==0:
# 이미지 URL
image_url = book_image[i].find_all('img')[0].get("src")
print(image_url)
# 이미지 이름
image_name = book_image[i].find_all('img')[0].get("alt")
print(image_name)
urllib.request.urlretrieve(image_url, directory_path+"/"+image_name+".jpg")
아래는 결과입니다.
소스코드 출력 결과
다운로드된 이미지들
이번 실습은 여기까지입니다. 하시다가 이해가 되지 않는 부분이 있으시면 질문을 올려주십시오.
아래 그림을 보시면 각 도서 정보는 <tr>...</tr> 태그에 감싸있는 것을 확인할 수 있습니다. 그리고 이러한 태그가 아주 많이 반복이 됩니다. 우리는 프로그램을 통해 순차적으로 탐색하면서 도서의 정보를 갖고 올 것입니다.
# 도서 정보를 포함하고 있는 html table
content = soup.find_all('table', {'id':'category_layout'})
#각 도서를 의미하는 tr 태그
book_list = content[0].find_all('tr')
# <tr> 태그 개수
print(len(book_list))
태그 개수는 최종적으로 33이 될 것입니다. 그 이유는 아래 그림처럼 다른 글도 <tr> 태그를 사용하기 때문입니다. 즉 도서 정보, 기타 글, 도서 정보, 기타 글... 이런 형식으로 되어 있습니다. 도서의 정보만 추출하기 위해 조건문을 두어 기타 글은 스킵하겠습니다.
# 첫번째 도서의 제목 갖고오기
for i in range(0, 1):
print(book_list[i].findAll("p")[0].text)
이번에는 전체 도서 정보를 갖고 오도록 하겠습니다. HTML 코드를 탐색하면 아시겠지만 제목은 <p>...</p>에 쌓여 있습니다.
# 전체 <tr> 태그에 있는 데이터를 반복문을 통해 추출
for i in range(0, len(book_list)):
# 도서 정보만 갖고 오기 위한 규칙
if i % 2 ==0:
# 도서 제목만 갖고 오기
print((book_list[i].find_all("p")[0].text).strip())
앞선 시간에 웹 사이트는 HTML이라는 구조화된 언어로 구성되었다고 설명을 드렸습니다. 여기서페이지 소스코드 보기는 HTML 소스코드를 보는 것입니다. 페이지 소스코드 보기는 키보드에서"F12"입니다.
2. 원하는 데이터의 위치 확인하기
페이지 소스코드 보기를 하셨다면 이젠 우리가 원하는 데이터가 HTML에서 어디에 위치하였는지를 확인해야 합니다.
아래 그림에서와 같이 icon을 클릭합니다. 이 기능은 해당 데이터가 있는 곳을 찾아줍니다.
해당 icon을 클릭한 후 좌측 이미지가 있는 부분에 마우스 커서(cursor)를 갖다 대시면 선택된 영역은 파랑색으로 변하는 것을 확인할 수 있습니다.
물론 한개의 데이터만 수집할 수 있습니다만 모든 데이터를 수집하기 위해 화면에 있는 모든 데이터가 포함 될 수 있는 위치를 찾고 마우스 좌클릭을 합니다.
좌클릭을 하시면 아래 그림처럼 우리가 원하는 데이터가 파랑색 소스코드에 포함되어 있다는 것을 확인할 수 있습니다.
그리고 삼각형 icon을 클릭해 숨겨져 있는 소스코드를 계속 확인합니다. HTML은 사이트의 layout을 일일이 정해주어야 하기 때문에 우리도 점진적으로 구조를 탐색할 필요가 있습니다. 이러한 과정을 거쳐 최종적으로 노이즈가 가장 적은"알맹이"부분을 찾는 것을 목표로 합니다.
드디어 "알맹이" 부분을 찾았습니다. 아래 두 그림을 보시면 첫번째 코드에 전체 데이터가 포함이 되어 있는 것을 알 수 있습니다. 두번째 그림에서는 1개의 데이터만 선택이 된것을 알 수 있습니다. 우리는 첫번째 그림의 소스코드 부분의 데이터를 프로그래밍을 통해 갖고 오면 됩니다.
각 이미지의 HTML 소스코드를 순차적으로 확인해 보시면 구조는 똑같고 데이터만 다른 것을 확인하실 수 있습니다. 즉 데이터 개수만큼 소스코드가 반복됩니다.