박람회 참가업체정보 크롤링

IngCoding·2023년 9월 6일
1

파이썬 #3 프로젝트

목록 보기
20/20

개요

  • 23.09.13.~23.09.16. 간 독일에서 진행되는 레하케어 박람회 참가업체(737개) 정보 크롤링
  1. 참가업체목록 url로 접근 후 shadow-dom 구조로 된 accept 버튼 클릭해줘야함
    • shadow host에 먼저 접근한뒤, shadow root 설정 후 선택자에 접근해줘야함.
    • 여러 선택자 다 접근해보고, 마우스도 이동시켜보고, send key로도 해보면서 해매다 html 뜯어보고 구글링해서 발견...
  2. 스크롤을 100회 자동 설정
  3. 목록에서 추출 가능한 정보 추출 (기업명, 위치, 업체별 url)
  4. 업체별 url을 for문으로 돌려서 개별 기업정보 추출
    • 처음 창 띄우고 accept 버튼 클릭시 계속 에러가 났는데 창 열린 뒤 time.sleep(5) 설정 후 정상작동
  5. 내용 중 반복되는 불필요한 텍스트는 삭제하고, DF 만들고 csv 파일로 변환함
  6. csv 파일은 구글시트로 옮겨서 활용
import sys
import os
import time
import warnings
warnings.filterwarnings('ignore')

import chromedriver_autoinstaller
import pandas as pd
import numpy as np
from selenium import webdriver
from selenium.webdriver.common.by import By

# 아래는 문제해결을 위해 시도해봤던 라이브러리.. 

# from pandas.io.html import read_html
# from selenium.webdriver.common.keys import Keys
# from selenium.webdriver.common.action_chains import ActionChains
# from selenium.webdriver.support.ui import WebDriverWait
# from selenium.webdriver.support import expected_conditions as EC
# from selenium.webdriver.support.select import Select
url = 'https://www.rehacare.com/vis/v1/en/search?oid=43530&lang=2&_query=&f_type=profile'

path = chromedriver_autoinstaller.install()
driver = webdriver.Chrome(path)
driver = webdriver.Chrome()
driver.get(url)

time.sleep(1)

# Accept All 버튼 클릭 
shadow_host = driver.find_element(By.CSS_SELECTOR, '#usercentrics-root')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, 'button.sc-eDvSVe.dkEaVU')
shadow_content.click()
def scroll_down(driver):
    driver.execute_script("window.scrollTo(0, 21431049)")

n = 100 # 숫자가 클수록 데이터 많이 가져옴
i = 0
while i < n: # 이 조건이 만족되는 동안 반복 실행
    scroll_down(driver) # 스크롤 다운
    i = i+1
    time.sleep(0.5)
# 불필요 데이터가 있어 738개 데이터 추출됨
names = driver.find_elements(By.CSS_SELECTOR, "h3")
len(names)
738
name_list = []

for a in names:
    name = a.text
    name_list.append(name)
# 불필요 데이터 삭제
del name_list[0]
len(name_list)
737
# 국가리스트
nations = driver.find_elements(By.CSS_SELECTOR, "h5")
len(nations)
737
nation_list = []

for b in nations:
    nation = b.text
    nation_list.append(nation)
# 각 기업별 프로필 링크
urls = driver.find_elements(By.CLASS_NAME, "media-module__link")
len(urls)
737
url_list = []
 
for c in urls:
    url = c.get_attribute("href")
    url_list.append(url)
    
len(url_list)
737
# company data 에서 추출할 정보들의 리스트 선언
phone_list = []
web_list = []
email_list = []
# 기업별 프로필 접근
for url in url_list[205:]: 

    path = chromedriver_autoinstaller.install()
    driver = webdriver.Chrome(path)
    driver = webdriver.Chrome()        
    driver.get(url)     
    
    time.sleep(5) # Shadow DOM 버튼 클릭 전 충분한 대기시간 필요 (PC 성능, 인터넷 환경에 따라 조정)
        
    # Accept All 버튼 클릭 
    shadow_host = driver.find_element(By.CSS_SELECTOR, '#usercentrics-root')
    shadow_root = shadow_host.shadow_root
    shadow_content = shadow_root.find_element(By.CSS_SELECTOR, 'button.sc-eDvSVe.dkEaVU')
    shadow_content.click()
    
    time.sleep(0.5)
    
    # company data 버튼클릭
    driver.find_element(By.CSS_SELECTOR, 'div.profile__cta-buttons > button').click()
    
    time.sleep(0.5)
    
    # company data 내에서 정보추출 (단, 각 항목마다 입력이 안되있는 경우가 있어 예외처리 진행)

    try: 
        phone = driver.find_element(By.CSS_SELECTOR, 'div.exh-contact-phone').text
        phone_list.append(phone)
    except:
        phone_list.append('none')
        
    try: 
        web = driver.find_element(By.CSS_SELECTOR, 'div.link-list.link-list--slim > ul > li > a').get_attribute("href")
        web_list.append(web)
    except:
        web_list.append('none')
        
    try: 
        email = driver.find_element(By.CSS_SELECTOR, 'div.exh-contact-email').text
        email_list.append(email)      
    except:
        email_list.append('none')          

    # 작업 종료 후 크롬창 종료
    driver.close()
# Data Frame 생성
df = pd.DataFrame({'name':name_list, 'nation':nation_list, 'url':url_list, 'phone':phone_list, 'web':web_list, 'email':email_list})
# 컬럼내 불필요한 텍스트 제거

df['phone']=df['phone'].str.strip()
df['phone']=df['phone'].str.replace('Phone:','')
df['phone']=df['phone'].str.replace('+','')

df['email']=df['email'].str.strip()
df['email']=df['email'].str.replace('E-mail:','')
# china 를 포함한 행삭제
df1 = df[~df['nation'].str.contains('china', na=False, case=False)]
os.chdir('C:\gino dev') # 파일이 저장될 디렉토리 설정

df.to_csv('23_reha_list.csv')
df1.to_csv('23_reha_list_notChina.csv')
profile
Data & PM

0개의 댓글