selenium 이용 중 페이지 로딩을 기다리는 2가지 방법

#1. 항목을 가져와야 하는데, 오류 발생

object of type 'WebElement' has no len()

이런 경우, elems = driver.find_element(By.CLASS_NAME, '클래스명') 로 elems를 선언할 때, 함수를 단수형태로 가져왔기에 배열이 아니라, 단순(1개의) 항목이라 len(elems) 하면 오류가 발생한다. driver.find_elements(By.CLASS_NAME, '클래스명') 처럼 복수로 가져올 수 있도록 수정
#2. Xpath로 설정했는데, WebDriver(selenium)이 항목을 식별할 수 없다.

Message: no such element: Unable to locate element:

이런 경우, 문서 구조에서 iframe 을 포함하는 것인지 확인. 네이버 카페의 경우 "cafe_main" 이라는 iframe내에 게시글들이 들어가 있는 구조라서,
iframe = driver.find_element(By.ID, 'cafe_main')
driver.switch_to.frame(iframe)
이런식으로 driver를 switch해줘야 함. 만약 다시 원래 페이지 구조로 돌아오려면,
driver.switch_to_default_content()를 호출하면 됨.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
import time
import datetime as d
from openpyxl import Workbook

xlsx = Workbook()
sheet = xlsx.active
sheet.append(['Title', 'Link', 'Published date'])

try:
    options = Options()
    options.add_experimental_option("detach", True)
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=options)
    
    keyword = '유형자산'                      
    driver.get('https://cafe.naver.com/parksamaccount')

    elem = driver.find_element(By.ID, 'topLayerQueryInput') 
    elem.send_keys(keyword)
    elem.send_keys(Keys.RETURN)

    iframe = driver.find_element(By.ID, 'cafe_main')
    driver.switch_to.frame(iframe)

    articles = driver.find_elements(By.CLASS_NAME, 'td_article')
    print(len(articles))
    for article in articles :
        title = article.find_element(By.TAG_NAME, "a")
        print(title.text)    
except Exception as e :
    print(e)    
finally :
    #driver.quit()
    print('ee')

#3. 책의 소스 또는 블로그의 소스가 실행이 안되는 경우, 참고하는 자료의 버전을 확인하고 버전을 맞춰본다.
print(library.__verison__) 확인후 재설치

Posted by 목표를 가지고 달린다
,

selenium 이용 중 페이지 로딩을 기다리는 2가지 방법

사실 3가지다. 첫번째는 sleep(3) 이런식으로 특정 시간(3~5초 정도) 기다리게 하는 것이다.
두번째는 클릭할 수 있는 객체가 나타낼때까지 기다기는 것이다. expected_conditions 포함

from selenium.webdriver.support import expected_conditions as EC

   driver.get('https://ww.instagram.com/')
    wait = WebDriverWait(driver, 5)   #최대 5초 기다림.
    cond = EC.element_to_be_clickable((By.LINK_TEXT, '로그인'))
    btn = wait.until(cond)
    btn.click()

세번째는 객체가 보여질 때까지 기다리는 것이다. expected_conditions 포함

from selenium.webdriver.support import expected_conditions as EC

    WebDriverWait(driver, 20).until(
        EC.visibility_of_element_located(
          (By.CLASS_NAME, "_a9_1"))).click()

 

Posted by 목표를 가지고 달린다
,

파이썬은 pandas 라이브러리를 활용하여, html 중에서 표만 추출하여 2차원 배열로 추출하는 함수를 제공한다.(엄청 편함)

 

준비단계 -----------------------------------------------

실제 해당하는 라이브러리는 내장되어 있지 않아 설치가 필요함

pip install pandas
pip install lxml
pip install html5lib
pip install BeautifulSoup4
pip install openpyl

---------------------------------------------------------
pip를 업그레이드가 필요한 경우
python -m pip install --upgrade pip
---------------------------------------------------------
WindowOS 10 인 경우, 직접 lxml 라이브러리를 다운받아 설치 필요
https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml |
사이트에 접속해서 자기 OS에 맞는 lxml을 다운받고, Python Shell에서 ‘pip install 다운받은파일.whl’ 실행

import pandas as pd
df = pd.read_html("https://en.wikipedia.org/wiki/All-time_Olympic_Games_medal_table")
print(df) # HTML 내용중 테이블 형태의 데이터를 실시간 추출함.
import pandas as pd
df = pd.read_html("https://en.wikipedia.org/wiki/All-time_Olympic_Games_medal_table", header=0, index_col=0)
print(df[1]) # 헤더를 열이름으로 정하고, 나라이름을 인덱스로 정함
import pandas as pd
df = pd.read_html("https://en.wikipedia.org/wiki/All-time_Olympic_Games_medal_table", header=0, index_col=0)
print(df[1].iloc[:, :5]) # 데이터의 앞에 5개만 추출

iloc 인덱스 방식 : 데이터의 순서에 따라 접근하는 것으로, 콤마를 중심으로 앞은 행, 뒤는 열에 접근하는 것. 따라서 iloc[:, :5]는 모든 행의 앞의 5개 열을 슬라이싱하라는 의미

import pandas as pd
df = pd.read_html("https://en.wikipedia.org/wiki/All-time_Olympic_Games_medal_table", header=0, index_col=0)
# print(df[1])
# print(df[1].iloc[:,:5]) # 모든 행의 처음부터 5개열..
summer=df[1].iloc[:,:5]
summer.columns=['경기수', '금','은','동', '계'] # 표의 컬럼 이름 정의
print(summer.sort_values('금', ascending=False)) # ‘금’ 숫자를 기준으로 정렬
summer.to_excel(‘하계올림픽메달.xlsx’) # 엑셀 파일로 저장(단 한줄)

pandas(panel datas, 패널자료)에 대해 알기 전, 1차원 배열 형태의 데이터 구조를 Series라고 부르고, 2차원 배열 형태의 데이터 구조를 DataFrame이라고 부른다. 파이썬에서는 numpy, pandas 같은 라이브러리를 활용하면 효율적이고 전문적인 데이터 분석을할 수 있다..

# pandas 연습하기

import pandas as pd
import numpy as np


index= pd.date_range('1/1/2000', periods=8)
print(index)
df = pd.DataFrame(np.random.rand(8,3), index=index, columns=list('ABC'))
print(df)
print(df[‘B’])
print(df['B'] > 0.4) # 0.4 보다 큰지 여부를 True / False로 표기
df04 = df[df['B'] > 0.4] # 특정값 이상만 배열에 담기
print(df04)
df['Total'] = df.sum(axis=1); # 합계 열 추가
df = df.sub(df['A'], axis=0) # A열을 빼기, A열은 모두 0으로 표기
df = df.div(df['C'], axis=0) # C열의 값으로 나누기
del df['E'], df['D'] # ‘E’,‘D’열 삭제
print(df.head()) # DataFrame의 첫5행만 확인
df.to_csv('test.cvs') # CSV 파일로 저장하기.
df = pd.read_csv(‘test.csv’, encoding=’cp949’ , index_col=0) # csv 파일 읽기
print(df.head())

- 데이터 프레임 행 우선 계산과 열 우선 계산

기본적으로 테이블(DataFrame)은 행우선(axis =0)으로, 열 방향으로 계산한다면, axis1로 변경해야 한다.

합계열을 추가하려면, df[‘E’] = np.sum(df, axis=1)를 실행하면 된다.

a = df.index.str.contains(name) # name변수를 포함한 index를 검색하여 행을 리턴

df2 = df[a] # 해당인덱스의 행전체 값을 저장

위의 내용대로, pandas의 read_html() 함수를 사용해서 테이블 형태의 자료를 추출한 후, 파일로 주기적 생성후, 주기적으로 개발자가 선호하는 언어(Java, PHP 등)로 DB에 넣어서 사용하면, 쉽게 크롤링을 할 수 있을 것 같다.

위 내용은 "모두의 데이터 분석 with 파이썬" 책을 읽으며 요약한 것으로, 개발자 기준에서 특징적인 것만 요약한 것이다.

다음에는 크롤링이라 명시된 책으로 정말 그외 특별한 무언가가 있는지.. 아니면 지금 이것을 활용하는 것뿐인 것인지 확인해 보자.

Posted by 목표를 가지고 달린다
,