Python

[Python] 파이썬으로 웹 크롤링 하기(코드 구현)-Skytrax홈페이지

zzheng 2024. 5. 22. 00:57

1. 웹 크롤링(Web Crawling)이란?

인터넷 상의 웹 페이지를 자동으로 탐색하고 수집하는 기술을 의미합니다. 

 

웹 크롤링을 할때, requests와 BeautifulSoup 라이브러리를 많이 사용하는데요.

이번 포스팅에서는 이 라이브러리를 사용하여 크롤링하는 방법에 대해 알아보도록 하겠습니다. 

 

★크롬과 크롬 드라이버가 설치가 완료됬으면, 5번부터 보시면 됩니다.★

 

2. 크롬 드라이버 설치

웹 크롤링을 위한 준비 단계로 크롬과 크롬 드라이버 설치가 필요합니다. 

 

<크롬 설치방법>

 '크롬'을 검색하시고 크롬 설치파일을 다운로드하는 링크로 이동하여 설치를 진행해주시면 됩니다. 

3. 크롬 버전 확인하기

크롬을 설치하셨으면, 버전을 확인해야됩니다. 크롬 드라이버를 다운받을때, 크롬의 버전과 일치되야 정상 작동이 가능합니다.

 

"크롬 창에서 우측상단에 (...) 표시 클릭 - 도움말 - Chrome 정보를 클릭" 하시면 크롬 버전을 확인할 수 있습니다.

 

4. 크롬 드라이버 설치하기

구글에 Chromedriver를 검색하셔서 다운하시거나, 아래의 Chromedriver 다운로드 페이지로 이동합니다.

https://chromedriver.chromium.org/downloads

 

위 홈페이지에서 자신의 버전과 같은 버전을 다운 받습니다.  

 

 

다운 받은 압축파일을 압축 해제하면, chromedriver.exe 파일이 나옵니다.

이후, 별도 설치할 필요없이 해당 파일을 필요한 경로로 이동하여 사용하시면 됩니다.

 

5. 라이브러리 다운로드(requests, beautifulsoup)

파이썬 웹 크롤링은 requests 라이브러리를 사용하여 웹 페이지의 HTML을 가져온 후,

beautifulsoup을 이용해 HTML 코드를 쉽게 다룰 수 있도록 파싱합니다.

 

따라서 먼저 requests, beautifulsoup 을 설치해주도록 합니다. 

pip install requests
pip install beautifulsoup4

 

6. 코드 구현

저는 SKYTRAX홈페이지를 크롤링을 진행해봤습니다. 

 

 

그중에서, https://www.airlinequality.com/airline-reviews/qatar-airways/ 홈페이지를 크롤링 해보겠습니다. 

 

F12를 눌러서 개발자 모드에 들어가서 원하는 값의 위치를 찾을 수 있습니다. 

저는 위 사이트 모든 정보를 크롤링 하였습니다. 또한 자동으로 페이지가 넘어가서 크롤링하도록 코드를 구현했습니다. 

 

 

코드 구현

from selenium import webdriver
import selenium
import time
import pandas as pd
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import re
from tqdm import tqdm

driver = webdriver.Chrome('/Users/haha/Crowling/chromedriver')
base_url = 'https://www.airlinequality.com/airline-reviews/qatar-airways/page/{}/'
url_ = 'https://www.airlinequality.com/airline-reviews/qatar-airways'
total_lst = []
driver.get(url_)
time.sleep(2)
html = driver.page_source 
soup = BeautifulSoup(html, 'html.parser')
page_num = int(soup.find('div', {'class':'pagination-total'}).text.split(' ')[4])//10
print(page_num)
for n in tqdm(range(80)): #80
    url = base_url.format(n+1)
    driver.get(url)
    time.sleep(2)
    html = driver.page_source 
    soup = BeautifulSoup(html, 'html.parser')


    for k in soup.find_all('article', {'itemprop':'review'}):
        try:
            rating = k.find('span', {'itemprop':'ratingValue'}).text
        except (IndexError, AttributeError):
            rating = None
        for i in k.find_all('div', {'class' : 'body'}):
            side_info = {}

            try:
                user_id = i.find('span', {'itemprop': 'author'}).find('span', {'itemprop': 'name'}).text
            except (IndexError, AttributeError):
                user_id = None
            
            try:
                user_country = i.find('h3').text.split(' (')[1].split(')')[0]
            except (IndexError, AttributeError):
                user_country = None
                
            try:
                date = i.find('time', {'itemprop': 'datePublished'}).text
            except (IndexError, AttributeError):
                date = None
                
            try:
                verified = i.find('em').text
            except (IndexError, AttributeError):
                verified = None
                
            try:
                review_text = i.find('div', {'class':'text_content'}).text.split('| ')[1]
            except (IndexError, AttributeError):
                review_text = None

            for j in i.find('table', {'class': 'review-ratings'}).find_all('tr'):
                key = j.find_all('td')[0].text
                if j.find('td', {'class': 'review-rating-stars stars'}):
                    value = len(j.find_all('span', {'class': 'star fill'}))
                else:
                    value = j.find_all('td')[1].text
                side_info[key] = value    
                
            total_lst.append([user_id, user_country, date, verified, review_text, side_info, rating])

 

데이터 프레임으로 변환하기

info = pd.DataFrame(total_lst, columns = ['User_ID', 'User_Country', 'Date', 'Trip_Verified', 'reviews', 'side_info', 'Rating'])#컬럼 지정해주기
print( pd.json_normalize(info['side_info']))