여러 페이지 동시 크롤링 위한 url 구조 활용

1. url 주소를 통한 웹페이지 구조 파악

: 유의미한 수준의 설득력 있는 인사이트를 도출하기 위해서는 충분한 양의 로우 데이터를 확보하는 것이 중요하다. 하지만 일반적으로 방대한 양의 데이터는 여러 페이지에 걸쳐 나열되어 있는 경우가 많기에 페이지마다 따로 크롤링 작업을 진행할 경우 모을 수 있는 데이터는 극히 제한적이다. 결국 여러 페이지에 걸친 크롤링 작업을 자동화하는 기술이 중요한데 이를 위해 우선적으로 확인해야 하는 것이 url 주소이다. 

 

초기 페이지 유입 시 url (상품리스트 1페이지)

 온라인 쇼핑몰 내 상품리스트를 들어가면 일반적으로 url 주소는 위와 같이 나타난다. 복잡하기만 하고 특별한 구조가 보이지 않아 일반적으로 쓰이는 반복문을 적용하는게 쉽지 않아 보이는데 이때 쇼핑몰 페이지를 앞뒤로 한두번 이동하다보면 숨겨져 있던 웹페이지 url 구조를 확인할 수 있다.

 

페이지 이동 시 나타난 url (상품리스트 2페이지)

 실제로 상품리스트 상의 2번 페이지로 이동하니 위와 같이 url의 숨은 부분이었던 '&page=2' 부분이 나타남을 확인할 수 있었다. 다른 페이지도 추가적으로 확인해보기도 하고 url 주소 내 숫자를 임의적으로 바꿔가면서 'page=N' 부분만 수정한다면 페이지별 반복작업을 자동화 할 수 있는 url 구조라는 사실을 확인할 수 있었다.

 

2. for 반복문을 통한 여러 페이지 동시 크롤링

: url 구조를 통해 확인한 구조를 바탕으로 for 반복문을 사용한다면 여러페이지에 걸친 크롤링 작업을 자동화할 수 있다. url 구조 상에서 변화가 필요한 부분을 정의한 뒤에 해당 부분을 range 함수 등 범위를 지정하는 방법을 통해 원하는 범위 만큼 작업 가능하다.

import requests
from bs4 import BeautifulSoup

url : 'https://www.ssg.com/disp/category.ssg?dispCtgId=6000184784&sort=sale&page='

for i in range(1,10):
    res = requests.get(url+str(i))  #페이지 표시 부분 for 반복문으로 대체
    soup = BeautifulSoup(res.content,'html.parser')
    items = soup.select('a > em.tx_ko')
    
    for item in items:
        print(item.get_text())

 

3. 페이지 오류 방지하기 위한 대처 방안

: 여러 페이지를 동시에 작업하다보면 일부 페이지의 수신 오류에 따라 진행중인 크롤링 작업이 전체 취소되는 경우가 자주 발생한다. 이러한 상황을 사전에 방지하기 위한 한가지 방법으로 응답 코드(response code)를 통해 서버 정상 수신 여부를 확인하는 status_code를 사용할 수 있다.

 

 웹페이지 상의 데이터를 요청할 경우 서버로부터 응답코드(response code)를 받게 되는데 해당 코드는 HTTP 규격에 따라 200인 경우 정상을 나타내며 그렇지 않은 경우 수신에 문제가 있다는 의미이다. 따라서 status_code 함수를 통해 특정 페이지 요청 후의 응답 코드가 200인지 그렇지 않은지에 대한 조건문을 더함으로써 중도 오류 없이 데이터 추출이 가능하다.  

url = 'https://www.ssg.com/disp/category.ssg?dispCtgId=6000184784&sort=sale&page='

for i in range(1,10):    
    res = requests.get(url+str(i))
    
    if res.status_code != 200:
        print('페이지 없음')      # 페이지 수신을 못한 경우 오류 발생 방지
    else:
        soup = BeautifulSoup(res.content,'html.parser')
        items = soup.select('a > em.tx_ko')
    
        for item in items:
            print(item.get_text())

+ Recent posts