본문 바로가기

Python Programming/Notes

Web_Crawler(3)_HTML

HTML Crawling

해당 포스팅은 kgitbank의 웹크롤링 수업에 대한 내용을 일부 발췌하여 정리한 내용이다.
지난 Web Crawler(1), (2) 포스팅에서 JSON과 XML 형식 파일을 크롤링하는 방법에 대해 다루었다.

HTML은 XML과 어떻게 다를까?

  • XML은 태그 이름이 태그 안 정보의 제목 역할을 할 수 있다.
  • HTML의 경우 태그 이름이 태그 안에 있는 정보와 관련이 없다는 특징이 있다.
  • 이를 "HTML 태그"라고 부르며, 내용적 의미보다는 디자인/기능적 의미를 지닌다.
  • 따라서, 태그 이름이 같은 여러 개의 정보 중에서 내가 관심 있는 것을 가져올 수 있어야 한다.

 

Best Seller 50

오늘 사용할 URL은 알라딘 중고서점 사이트이다. 먼저, 베스트셀러 책 50권에 대한 정보를 간단하게 불러와 볼 것이다.

import requests
import bs4

url = 'https://www.aladin.co.kr/shop/common/wbest.aspx?BranchType=1&start=we'
response = requests.get(url).text 
one_page = bs4.BeautifulSoup(response)
one_page.find_all('b')
[<b>에세이</b>,
 <b>인문학</b>,
 <b>겁내지 않고 그림 그리는 법</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 87,770</b>,
 <b>130층 나무 집</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 56,980</b>,
 <b>질서 너머</b>,
 <b><span class="">16,020</span>원</b>,
 <b> 100,120</b>,
 <b>흔한남매 7</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 109,485</b>,
 <b>비극의 탄생</b>,
 <b><span class="">15,750</span>원</b>,
 <b> 54,930</b>,
 <b>주택과 세금</b>,
 <b><span class="">7,000</span>원</b>,
 <b> 96,320</b>,
 <b>달러구트 꿈 백화점</b>,
 <b><span class="">12,420</span>원</b>,
 <b> 368,751</b>,
 <b>진격의 거인 33</b>,
 <b><span class="">4,500</span>원</b>,
 <b> 33,980</b>,
 <b>주린이가 가장 알고 싶은 최다질문 TOP 77</b>,
 <b><span class="">16,200</span>원</b>,
 <b> 223,250</b>,
 <b>2021 큰별쌤 최태성의 별★별한국사 한국사능력검정시험 심화(1, 2, 3급) 상</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 66,320</b>,
 <b>2021 큰별쌤 최태성의 별★별한국사 한국사능력검정시험 심화(1, 2, 3급) 하</b>,
 <b><span class="">12,600</span>원</b>,
 <b> 62,120</b>,
 <b>설민석의 한국사 대모험 16</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 40,440</b>,
 <b>케이팝 시대를 항해하는 콘서트 연출기</b>,
 <b><span class="">13,320</span>원</b>,
 <b> 39,890</b>,
 <b>이상한 과자 가게 전천당 10</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 73,520</b>,
 <b>2021 큰별쌤 최태성의 별★별한국사 기출 500제 한국사능력검정시험 심화(1.2.3급)</b>,
 <b><span class="">17,100</span>원</b>,
 <b> 92,905</b>,
 <b>공정하다는 착각</b>,
 <b><span class="">16,200</span>원</b>,
 <b> 245,569</b>,
 <b>모래알만 한 진실이라도</b>,
 <b><span class="">14,400</span>원</b>,
 <b> 130,045</b>,
 <b>주술회전 13</b>,
 <b><span class="">4,500</span>원</b>,
 <b> 77,720</b>,
 <b>어린이라는 세계</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 168,574</b>,
 <b>어쩌면 스무 번</b>,
 <b><span class="">12,150</span>원</b>,
 <b> 30,590</b>,
 <b>천문학자는 별을 보지 않는다</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 55,410</b>,
 <b>해커스 토익 기출 보카 TOEIC VOCA 단어장</b>,
 <b><span class="">11,610</span>원</b>,
 <b> 273,708</b>,
 <b>강방천의 관점</b>,
 <b><span class="">22,500</span>원</b>,
 <b> 37,045</b>,
 <b>새벽의 연화 33</b>,
 <b><span class="">4,500</span>원</b>,
 <b> 19,430</b>,
 <b>우연의 질병, 필연의 죽음</b>,
 <b><span class="">12,600</span>원</b>,
 <b> 7,380</b>,
 <b>마지막 몰입</b>,
 <b><span class="">15,120</span>원</b>,
 <b> 54,255</b>,
 <b>2030 축의 전환</b>,
 <b><span class="">16,200</span>원</b>,
 <b> 213,358</b>,
 <b>어떻게 말해줘야 할까</b>,
 <b><span class="">15,750</span>원</b>,
 <b> 230,723</b>,
 <b>푸른 사자 와니니 3</b>,
 <b><span class="">9,720</span>원</b>,
 <b> 62,580</b>,
 <b>ETS 토익 정기시험 기출문제집 1000 Vol. 2 Reading (리딩)</b>,
 <b><span class="">16,020</span>원</b>,
 <b> 179,394</b>,
 <b>ETS 토익 정기시험 기출문제집 1000 Vol. 2 Listening (리스닝)</b>,
 <b><span class="">16,020</span>원</b>,
 <b> 166,281</b>,
 <b>파친코 1</b>,
 <b><span class="">13,050</span>원</b>,
 <b> 91,750</b>,
 <b>부자 아빠 가난한 아빠 1 (20주년 특별 기념판)</b>,
 <b><span class="">14,220</span>원</b>,
 <b> 74,144</b>,
 <b>재혼황후 5</b>,
 <b><span class="">12,600</span>원</b>,
 <b> 14,970</b>,
 <b>평범한 결혼생활</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 57,920</b>,
 <b>2021 선재국어 실전 봉투 모의고사 1</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 21,630</b>,
 <b>파친코 2</b>,
 <b><span class="">13,050</span>원</b>,
 <b> 86,820</b>,
 <b>아몬드 (양장)</b>,
 <b><span class="">10,800</span>원</b>,
 <b> 137,330</b>,
 <b>휴먼카인드</b>,
 <b><span class="">19,800</span>원</b>,
 <b> 38,440</b>,
 <b>수학 잘하는 아이는 이렇게 공부합니다</b>,
 <b><span class="">15,120</span>원</b>,
 <b> 50,230</b>,
 <b>2021 수제비 정보처리기사 실기 (1권+2권 합본세트) 2020년 기출 문제 수록</b>,
 <b><span class="">29,700</span>원</b>,
 <b> 40,790</b>,
 <b>전국축제자랑</b>,
 <b><span class="">13,500</span>원</b>,
 <b> 26,710</b>,
 <b>깊은 밤 필통 안에서</b>,
 <b><span class="">9,000</span>원</b>,
 <b> 29,240</b>,
 <b>좀비고등학교 코믹스 23</b>,
 <b><span class="">8,820</span>원</b>,
 <b> 22,940</b>,
 <b>체인소 맨 5</b>,
 <b><span class="">4,500</span>원</b>,
 <b> 24,480</b>,
 <b>흔한남매 불꽃 튀는 우리말 1</b>,
 <b><span class="">11,700</span>원</b>,
 <b> 43,460</b>,
 <b>환한 숨</b>,
 <b><span class="">12,600</span>원</b>,
 <b> 26,760</b>,
 <b>푸른 사자 와니니</b>,
 <b><span class="">9,720</span>원</b>,
 <b> 107,010</b>,
 <b>2021 선재국어 나침판 실전 모의고사 Vol.1</b>,
 <b><span class="">18,900</span>원</b>,
 <b> 46,045</b>,
 <b>귀멸의 칼날 22</b>,
 <b><span class="">4,500</span>원</b>,
 <b> 50,975</b>]
  • 위의 결과에서 확인할 수 있듯이, 'b'라는 태그명을 검색하면, 해당 태그를 포함하는 여러 가지 정보들이 책제목과 섞여있음을 알 수 있다.
  • 따라서, 책제목을 특정지을 수 있어야 한다.
  • 사이트에서 책 제목에 해당하는 부분을 우클릭한 후 '검사' 버튼을 클릭하면 아래와 같은 개발자 도구를 확인할 수 있다.

 

  • 개발자 도구를 통해 'div' 태그의 'ss_book_box' 클래스 내에 포함된 'b' 태그 부분에 제목이 입력되어 있음을 알 수 있다.
  • 따라서 아래와 같이 find_all 함수를 활용하여 제목 정보를 특정하는 코드를 작성하였다.
  • for문 내에서 text 함수를 활용하여 태그를 지우는 작업을 수행했다.
books = one_page.find_all('div', {'class' : 'ss_book_box'})
book_titles = []
for book in books:
    title = book.find_all('b')[0].text 
    book_titles.append(title)
book_titles
['겁내지 않고 그림 그리는 법',
 '130층 나무 집',
 '질서 너머',
 '흔한남매 7',
 '비극의 탄생',
 '주택과 세금',
 '달러구트 꿈 백화점',
 '진격의 거인 33',
 '주린이가 가장 알고 싶은 최다질문 TOP 77',
 '2021 큰별쌤 최태성의 별★별한국사 한국사능력검정시험 심화(1, 2, 3급) 상',
 '2021 큰별쌤 최태성의 별★별한국사 한국사능력검정시험 심화(1, 2, 3급) 하',
 '설민석의 한국사 대모험 16',
 '케이팝 시대를 항해하는 콘서트 연출기',
 '이상한 과자 가게 전천당 10',
 '2021 큰별쌤 최태성의 별★별한국사 기출 500제 한국사능력검정시험 심화(1.2.3급)',
 '공정하다는 착각',
 '모래알만 한 진실이라도',
 '주술회전 13',
 '어린이라는 세계',
 '어쩌면 스무 번',
 '천문학자는 별을 보지 않는다',
 '해커스 토익 기출 보카 TOEIC VOCA 단어장',
 '강방천의 관점',
 '새벽의 연화 33',
 '우연의 질병, 필연의 죽음',
 '마지막 몰입',
 '2030 축의 전환',
 '어떻게 말해줘야 할까',
 '푸른 사자 와니니 3',
 'ETS 토익 정기시험 기출문제집 1000 Vol. 2 Reading (리딩)',
 'ETS 토익 정기시험 기출문제집 1000 Vol. 2 Listening (리스닝)',
 '파친코 1',
 '부자 아빠 가난한 아빠 1 (20주년 특별 기념판)',
 '재혼황후 5',
 '평범한 결혼생활',
 '2021 선재국어 실전 봉투 모의고사 1',
 '파친코 2',
 '아몬드 (양장)',
 '휴먼카인드',
 '수학 잘하는 아이는 이렇게 공부합니다',
 '2021 수제비 정보처리기사 실기 (1권+2권 합본세트) 2020년 기출 문제 수록',
 '전국축제자랑',
 '깊은 밤 필통 안에서',
 '좀비고등학교 코믹스 23',
 '체인소 맨 5',
 '흔한남매 불꽃 튀는 우리말 1',
 '환한 숨',
 '푸른 사자 와니니',
 '2021 선재국어 나침판 실전 모의고사 Vol.1',
 '귀멸의 칼날 22']

HTML 파일에서는 클래스를 특정하여 작업 수행 시, 이와 같이 베스트 셀러 50권의 정보를 가져올 수 있다.

 

함수 만들기

import requests
import bs4

def best_book_page():
    url = 'https://www.aladin.co.kr/shop/common/wbest.aspx?BranchType=1&start=we'
    return requests.get(url).text

def one_page_all_books(response): 
    one_page = bs4.BeautifulSoup(response)
    books = one_page.find_all('div', {'class' : 'ss_book_box'})
    book_titles = []
    for book in books:
        title = book.find_all('b')[0].text
        book_titles.append(title)
    return book_titles

 

중고서점 재고 확인 - 동적 크롤링

  • 베스트 셀러에서 확인한 특정 도서에 대한 관심을 가지게 되면, 중고 서점에서 해당 책 제목을 검색할 것이다.
  • 중고서점에 접속하여 베스트셀러를 알아보고, 중고 서적 재고가 있는 지 확인하는 모든 프로세스를 동적 크롤링으로 자동화하는 시스템을 간단하게 생성해 볼 것이다.
  • 이 과정에서, selenium이라는 물리 드라이버를 설치해야 한다.
!pip install selenium
Requirement already satisfied: selenium in c:\users\esthe\appdata\local\programs\python\python38-32\lib\site-packages (3.141.0)
Requirement already satisfied: urllib3 in c:\users\esthe\appdata\local\programs\python\python38-32\lib\site-packages (from selenium) (1.25.9)


WARNING: You are using pip version 20.2.4; however, version 21.0.1 is available.
You should consider upgrading via the 'c:\users\esthe\appdata\local\programs\python\python38-32\python.exe -m pip install --upgrade pip' command.
from selenium import webdriver
driver = webdriver.Chrome('chromedriver.exe') 
  • 웹드라이버로부터 크롬 실행 파일을 실행시키면, 아래와 같은 빈 크롬 창이 뜨게 된다.

 

  • 여기서, drive 실행이 되지 않을 수도 있다. 해당 경우에는 pwd()를 통해 현재 working directory를 확인한 후 chrome driver 실행파일을 복사한 후 실행해야 한다.
  • 알라딘 사이트에 접속해 보기 전에, 기본 웹브라우저 조작법을 짚고 넘어가 보자.
  • 드라이버에서 실행 가능한 메인 동작 세 가지는 바로 get, back, close이다.
    • get을 통해 url 주소로 이동하고,
    • back을 통해 뒤로 가기를 실행하며,
    • close 하여 크롬 창을 종료할 수 있다.
import time
# 기본 웹브라우저 조작법

driver = webdriver.Chrome('chromedriver.exe')
time.sleep(2)

url = 'https://search.naver.com/search.naver?sm=tab_hty.top&where=nexearch&query=djkslfjkdk&oquery=a%3Bsldkfjdksl&tqi=huz01wp0JywssbOFQ5Kssssss7C-369741'
driver.get(url) # url 주소로 이동

time.sleep(2)
driver.back() # 뒤로 가기

time.sleep(2)
driver.close() # 크롬 창 끄기

 

알라딘 온라인 중고샵에 접속하기

중고샵에 접속하여 검색하는 과정은 아래의 프로세스를 따른다.

 

검색 박스에 책 제목을 타이핑하기

  • 1) 검색 박스(대상)의 위치를 특정한다.
  • 2) 검색 박스(대상)를 선택한다.
  • 3) 타이핑 한다.

오른쪽에 있는 검색 버튼을 누르기

  • 1) 검색 버튼(대상)의 위치를 특정한다.
  • 2) 검색 버튼(대상)을 선택한다.
  • 3) 클릭한다.
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
import time
import pandas as pd

driver = webdriver.Chrome('chromedriver.exe')

url = 'https://www.aladin.co.kr/home/wusedshopmain.aspx?start=we_tab'
driver.get(url)

all_result = []

best_books = one_page_all_books(best_book_page()) #베스트셀러 책 50권 list

for book in best_books[0:10]:
    box_path = '//*[@id="SearchWord"]' 
    input_box = driver.find_element_by_xpath(box_path) 
    input_box.clear() # 지우는 메서드
    input_box.send_keys(book)

    btn_path = '//*[@id="global_search"]/input'
    search_btn = driver.find_element_by_xpath(btn_path) 
    search_btn.click() 

    response = driver.page_source
    all_result.append({'title' : book, 'result' : str(one_page_all_books(response))})

pd.DataFrame(all_result)
  title result
0 겁내지 않고 그림 그리는 법 []
1 130층 나무 집 []
2 질서 너머 ['Beyond Order: 12 More Rules for Life (Paperb...
3 흔한남매 7 ['말할 수 없는 남매 7', '흔한남매의 흔하지 않은 음악이론 7', '노 게임 ...
4 비극의 탄생 ['비극의 탄생', '비극의 탄생.반시대적 고찰', '비극의 탄생', '비극의 탄생...
5 주택과 세금 ['고동호의 농지.농가주택과 세금', '신방수 세무사의 주택임대사업자등록과 절세 비...
6 달러구트 꿈 백화점 ['달러구트 꿈 백화점', '달러구트 꿈 백화점 - 주문하신 꿈은 매진입니다']
7 진격의 거인 33 ['진격의 거인 Before the fall 1~17 + 중학교 1~11 + 항(抗...
8 주린이가 가장 알고 싶은 최다질문 TOP 77 []
9 2021 큰별쌤 최태성의 별★별한국사 한국사능력검정시험 심화(1, 2, 3급) 상 []
  • 베스트셀러 50권 중 10권에 대해 자동 검색 시스템을 생성하여 실행한 결과이다.
  • 아래와 같이 마우스 클릭과 검색에 대한 모든 동작이 자동화되어 일괄적으로 처리되어 위와 같은 데이터프레임이 생성된다.