python BeautifulSoup을 이용한 크롤링

vector13·2021년 8월 3일

BeautifulSoup을 이용해 저번에 크롤링을 한 것을 포스팅 한 적이 있다.
그 당시 크롤링 하던 대상에 업데이트 된 내용이 있어서 다시 크롤링을 시행할 겸 저번보다 정리된 내용을 기록용으로 써봄.

1. 크롤링할 대상의 주소 목록 리스트업

f = open("", 'w')안에 저장할파일명 예시로 file1로 넣고
url = 크롤링 대상 페이지주소의 공통된 주소
(예를 들면 www.... page=0 또는 page=1 이런식으로 반복됨 )

import urllib.request
from bs4 import BeautifulSoup

f = open("file1", 'w')

# for 반복문으로 각 상품 링크 저장한다.
# 크롤링대상 페이지가 페이지별 &page=0 또는 &page=1 이기 때문에 str(i)를 이용해서 반복문
# 나는 4페이지까지 있기 때문에 반복문 4번돌리기
for i in range(0, 4, 1):
    url = "https://www.eider.co.kr/eider/ko/%EC%97%AC%EC%84%B1%EC%9D%98%EB%A5%98/%ED%8B%B0%EC%85%94%EC%B8%A0/c/EI002002000?q=%3Acreationtime-desc%3AmobileYn%3AFALSE&page=" + str(i)
    req = urllib.request.Request(url)
    sourcecode = urllib.request.urlopen(url).read()
    soup = BeautifulSoup(sourcecode, "html.parser")
    
    for href in soup.find("div", class_="각 크롤링대상의 페이지주소를 가지고있는 div태그의 class이름").find_all("div", class_="productGridItem"):
        print(href.find("a")["href"])
        f.write(href.find("a")["href"] + '\n')
    i += 1

f.close()

실행시키면

이런식의 주소모음이 완성된다. (이번의 경우 70개 주소가 크롤링되었음)
이 주소의 경우 앞에 대표주소 www.대표주소.co.kr뒤에 붙으면 완성되는 주소들이다.

2. 각 대상페이지 별 얻고싶은 정보가 어느 속성인지 파악

얻고싶은 정보를 가진 태그의 id나 class를 파악하고 유일한 속성을 찾아낸 후
아까 얻은 주소목록(주소모음)에 하나씩 접근해서 유일한 속성에 접근해 n번 반복시행하면
내가 원하는 정보를 가진 csv파일 (또는 txt 파일 등등)(여기서는 예시로 file2.csv로 쓰겠음) 을 얻을 수 있다.

코드로 살펴보면
아까 주소모음 개수만큼 빈 문자열 리스트 rs를 만들어주고
anchor를 이용해서 id나 class를 select해서 data에 get_text()로 써주는 형식으로 진행된다.

id의 경우 #를, class의 경우 . 를 이용하고 해당하는 것이 여러개일경우 select_one으로 첫번째 발견된 것만 해당하게 한다.

id나 class로도 찾을 수 없는 경우 태그를 이용하는데
#제조년월의 경우 .tbl_style_04 tbody tr:nth-of-type(8) td"):
로 찾고있는데, 이는 bl_style_04클래스의 tbody 태그의 8번째 tr태그 의 td태그를 가져오라는 뜻이다.

import csv
from bs4 import BeautifulSoup
from urllib.request import urlopen

f = open("file1.txt", 'r')
lines = f.readlines()
f.close()

# print(lines) #lines 변수에 리스트로 저장되어있음
rs = ['', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '',
      '', '', '', '', '', '', '', '', '', '']
# len(rs) #70 아까 주소모음 개수만큼 
# f = open("sample1아이더코드이름색상.txt", 'w')
f = open(f'file2.csv', 'w', encoding='utf-8', newline='')
csvWriter = csv.writer(f)

for i in range(0, len(rs)):
    rs[i] = 'http://www.eider.co.kr' + lines[i]
    with urlopen(rs[i]) as response:
        soup = BeautifulSoup(response, 'html.parser')
        #모델번호
        for anchor in soup.select("#div_productCode"):
            data = anchor.get_text()+" $ "
        #계절
        for anchor in soup.select_one(".prod-flag span"):
            #print(anchor)
            data += anchor+" $ "
        #제품명
        for anchor in soup.select("#p_productName"):
            data += anchor.get_text()+" $ "
        #가격 -처리하기
        for anchor in soup.select(".prod-price"):
            #print(anchor)
            data += anchor.get_text()+" $ "
        '''
        #색상
        for anchor in soup.select("#em_color"):
            print(anchor)
            data += anchor.get_text()+" $ "
        
        #사이즈
        for anchor in soup.select_one("#productSizeInfo"):
            print(anchor)
            data += anchor+" $ "
        
        #소재
        for anchor in soup.select_one(".tbl_style_04 tbody tr td"):
            print(anchor)
            data += anchor+" $ "
            #data += anchor.get_text()
        '''
        #제조년월
        for anchor in soup.select_one(".tbl_style_04 tbody tr:nth-of-type(8) td"):
            print(anchor)
            data += anchor+" $ " +"\n"


            #csvWriter.writerow(data)

        # print(i+"번째 " +data+"\n")
        f.write(data)
f.close()

이런식으로 한 코드를 이용해 정보를 가져오는 경우 데이터가 정돈되지 않을 가능성이 크다. 이때는 엑셀을 이용하여 데이터를 정돈해주거나 양상이 비슷한 것끼리 묶어서 가져온 다음 데이터를 합치면 된다. (편하고 빠른대로.. )

저 코드의 경우 한 상품을 ->한줄로 취급, $를 이용하여 분리하였기 때문에 엑셀에서 데이터>텍스트나누기> 구분기호로분리> 기타 > $를 기준으로 나누기 하면 가장 빠르게 정리된다.

3.(번외) 저장된 csv파일 한글이 깨지는 경우

방법1. 파이참 사용한 경우 파이참으로 csv파일을 열어서 한글이 손상되지않아있으면 그것을 사용함
방법2. csv가 아니라 xlsx엑셀 파일로 저장한 다음 csv로 바꾸어 저장하기

profile
HelloWorld! 같은 실수를 반복하지 말기위해 적어두자..

0개의 댓글