BeautifulSoup을 이용해 저번에 크롤링을 한 것을 포스팅 한 적이 있다.
그 당시 크롤링 하던 대상에 업데이트 된 내용이 있어서 다시 크롤링을 시행할 겸 저번보다 정리된 내용을 기록용으로 써봄.
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뒤에 붙으면 완성되는 주소들이다.
얻고싶은 정보를 가진 태그의 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()
이런식으로 한 코드를 이용해 정보를 가져오는 경우 데이터가 정돈되지 않을 가능성이 크다. 이때는 엑셀을 이용하여 데이터를 정돈해주거나 양상이 비슷한 것끼리 묶어서 가져온 다음 데이터를 합치면 된다. (편하고 빠른대로.. )
저 코드의 경우 한 상품을 ->한줄로 취급, $를 이용하여 분리하였기 때문에 엑셀에서 데이터>텍스트나누기> 구분기호로분리> 기타 > $를 기준으로 나누기 하면 가장 빠르게 정리된다.
방법1. 파이참 사용한 경우 파이참으로 csv파일을 열어서 한글이 손상되지않아있으면 그것을 사용함
방법2. csv가 아니라 xlsx엑셀 파일로 저장한 다음 csv로 바꾸어 저장하기