본문 바로가기

공부/웹크롤링

[Python/파이썬] BeautifulSoup, Selenium으로 웹크롤링

매장 홈페이지에서 정보를 스크래핑해야할 일이 많았다. 이 경험으로 깨달은 것들을 정리해보려 한다.

 

1. 크롤링하기 전에 내가 원하는 URL로 아래 코드를 먼저 돌려보기!

res = requests.post('https://www.elandretail.com/store02.do)
res.encoding = 'etf-8'  # 또는 'euc-kr'
html = res.text 
soup = BeautifulSoup(html, 'html.parser') 
soup

- 위 코드를 돌리면 결과가 내가 원하는 태그가 포함되어 나오는 경우가 있고, 아닌 경우가 있다. 예를 들어, 추출 정보가 팝업창 형태로 되어있고, 클릭해도 URL주소가 바뀌지 않는 경우에는 보이는 URL로 가져오기가 어렵다.

이럴 땐 밑의 두 가지 방법으로 해결한다. 

  •  Newtork 콘솔창에서 작동되는 동적 페이지의 우회주소를 통해 Beautifulsoup을 이용하는 방법
  • Selenium을 이용하여 직접 웹을 동적으로 실행시키는 방법

경우에 따라 두 가지를 섞어쓰기도 한다. 난 시스템에 적용시킬 목적은 아니라 다양한 방법을 이용했다.

 

<이랜드리테일 매장정보 크롤링하기>

\NETWORK콘솔창에서 xhr이나 document타입 확인하기

step1)

필자의 경우에는 주소를 하나씩 눌러보며 동적페이지의 주소가 어떻게 바뀌는 지 파악하였다. Priview버튼을 이용해 내가 원하는 정보가 나타나있는지 살펴봤다. 있다면 Header버튼 눌러 Request URL에 있는 주소를 가져온다. 위의 경우 'https://www.elandretail.com/store02.do?branchID=00110002&lang=000600KO'가 동적페이지로 동작하고 있다는 걸 알게 되어 URL을 수정하여 불러온 html에 정보가 담겨있는 지 다시 확인했다.

 

 

 

step2)

위의 이랜드리테일의 층별안내를 가져오는 데에 층을 하나씩 눌러서 정보를 확인해야했다. 이때 필요한 것이 Selenium 라이브러리이다. 웹페이지를 크롤링하는데 클릭하거나 로그인을 하는 작업등을 수행해준다. 

만약 BeautfulSoup을 이용해 태그를 가져오고 싶다면 driver.Page_source를 이용하면 된다.

### TAB이 안먹혀서 INDENT는 알아서 수정하기...

for s in range(51): 
driver.get('https://www.elandretail.com/store02.dobranchID=001100{}&lang=000600KO'.format(str(s+1).zfill(2))) 
flo_total = driver.find_elements_by_tag_name('b') 
store = driver.find_elements_by_tag_name('h2')

for k in range(len(flo_total)): 

### 층버튼의 규칙 파악하기! 이랜드의 형태 -> //*[@id="id_00020B1F"]/a/b 
driver.find_element_by_xpath('//*[@id="id_00020{}"]/a'.format(flo_total[k].text.zfill(3))).click() 
time.sleep(3)   # 클릭 후에는 대기를 걸어줘서 HTML이 잘 로딩되게끔..!
name = driver.find_elements_by_class_name('brand') 
tel = driver.find_elements_by_class_name('tel')

 

 

step3)

가져온 HTML의 태그의 값을 불러올 때는 text함수를 이용한다. 유의할 점은 text는 List에서 사용불가!

따라서 for문을 이용한다. 또한 엑셀 형태로 반환하기 위해 DataFrame형태로 만들었다.

for i, j in zip(name,tel): 
f = flo_total[k].text 
n = i.text 
t = j.text 
d = store[len(store)-1].text 

df = df.append(pd.DataFrame([[d,f,n,t]], columns=['brand','floor','name','tel']), ignore_index=True)

 

결과

 

 

 

 

2. 파이썬 짚고가기

 

- 새로운 함수

용도 함수 입력 결과
입력값을 일정한 길이로 정규화하고 싶을때! s.zfill(int n) '1'.zfill(3) '001' 

for문에 2개 인자를 넣고 싶을때!

(2개 인자가 인덱스와 값인 경우는 enumerate)

zip(a,b)

for i, j in zip('[1,2],[3,4]'):

print(i,j)

1,3

2,4

 

- BeautifulSoup에서 select함수 이용해 태그 가져오기

용도 특징 입력
태그명 태그명만 soup.select('태그명')
클래스명 . 붙이기 soup.select('.클래스명')

상위태그와 하위태그 관계

> : 바로 아래 위치(자식관계)

띄어쓰기 : 자손관계일때

soup.select('상위태그명 > 하위태그명')

soup.select('상위태그명 하위태그명')

아이디명

#붙이기

soup.select('#아이디명')

속성의 값 이용

태그명뒤에 속성 지정

soup.select('태그명[속성1=값1]')

 

- Selenium에서 find_element~~이용해 태그 가져오기

한 개 태그를 가져오고 싶다 -> find_element

여러 개 태그를 가져오고 싶다 -> find_elements

로 나눠지며 아래의 표는 element 기준이다. 많이 쓰는 거만 정리했다.

driver.find_element_by_name("태그명") 태그를 모두 가져오고 싶을 때 유용
driver.find_element_by_id("아이디명") 태그 내에서 하나만 가져올 때 유용
driver.find_element_by_xpath("xpath경로") 반복해서 가져올 때 규칙을 이용하면 유용

 

'공부 > 웹크롤링' 카테고리의 다른 글

[python/파이썬] 크롤링 초보가 겪은 위기 정리  (0) 2020.02.21