앞의 글에서 이어지는 내용이다. 이번 글에서는 decompose와 for문에 대해 짧게 짚고 넘어가려 한다.
전체코드
def getStock(isbn):
url = 'http://www.kyobobook.co.kr/prom/2013/general/StoreStockTable.jsp?barcode=' + isbn + '&ejkgb=KOR'
res = requests.get(url)
soup = BS(res.text, 'html.parser')
# 비어있는 태그들 삭제
[x.decompose() for x in soup.findAll(lambda tag: (not tag.contents or len(tag.get_text(strip=True)) <= 0))]
store = soup.select('th')
num = soup.select('a')
stock = {}
for i, j in zip(store, num):
i = i.text
i = i.strip()
if i == '':
pass
else:
stock[i] = j.text
return stock
어떻게 크롤링을 해야 효율적일까?
앞서 말했던 교보문고 재고 사이트에 접속하면 다음과 같은 결과가 나온다. 참고로 isbn이 9788954651134인 이 책은 이번에 재고 사이트를 만들면서 주구장창 검색했던 한강 작가의 '흰'이다. 좋아하는 작가인데다가 제목이 짧아 검색하기 쉬워서..ㅎㅎㅎ
Beautiful Soup으로 필요한 정보만 뽑아오기 위해서는 소스코드를 확인해서 html 태그, class, id 등을 어떻게 이용해 파싱하는게 효율적일지 생각해야 한다(소스가 아주 긴 경우네는 `F12`를 눌러 개발자 도구를 이용하면 편리하다). 확인한 코드는 다음과 같다.
지점명은 th 태그를 받아와야 하고, 재고는 a태그를 받아와야 한다.
store = soup.select('th')
num = soup.select('a')
일반적인 사이트라면 th와 a 태그가 다른 요소에도 많이 사용되어 태그로만 파싱할 수 없었겠지만, 위 재고사이트는 정말 딱! 재고에 관한 내용만 있어서 class나 id를 쓸 필요가 없었다.
헌데 여기서 문제가 생긴다. 재고 tr을 보면 빈 td태그가 있는 걸 볼 수 있다. 표를 나누다보니 자연스럽게 생기는 공백 태그인데, 파싱 해오면 해당 내용까지 쓸데없이 다 받아올 수 밖에 없다. 그래서 짠 코드가 바로 아래 코드.
[x.decompose() for x in soup.findAll(lambda tag: (not tag.contents or len(tag.get_text(strip=True)) <= 0))]
decompose()는 BeautifulSoup에서 제공하는 메쏘드로, 해당 태그를 제외할 때 사용한다. 태그의 내용이 없는 것들을 x에 넣어서 해당 태그를 제거하는 코드를 for문으로 돌렸다.
이렇게 얻은 지점명과 재고를 딕셔너리로 합치기 위해 for문의 zip을 이용해서 같이 돌렸다. 지점명을 받아오는 i가 비어있으면 그냥 넘기고, 그렇지 않으면 stock에 같이 넣으라는 의미다.
stock = {}
for i, j in zip(store, num):
i = i.text
i = i.strip()
if i == '':
pass
else:
stock[i] = j.text
'만들기 > 재고 검색 사이트' 카테고리의 다른 글
04. Requests를 향한 여정 (0) | 2019.09.06 |
---|---|
02. 재고 크롤러(1) (0) | 2019.09.03 |
01. (0) | 2019.09.02 |