본문 바로가기
study/Python

[Python] 42. BeautifulSoup : html,xml 태그 분석 모듈, 셀레니움, 이미지 다운 받기

by 금이패런츠 2022. 7. 1.
728x90
반응형

1.BeautifulSoup : html,xml 태그 분석 모듈

2. 셀레니움

3.이미지 다운 받기

# -*- coding: utf-8 -*-
"""
Created on Fri Jul  1 09:03:32 2022

@author: KITCOOP
20220701.py
"""
'''
  범주형 데이터 : 값의 범위를 가진 데이터. 
                describe() 함수에서 조회시 제외.
  날짜 데이터 : pandas.date_range() : 날짜값을 범위 지정해서 조회
               df["Date"] : datetime 형
               df["Date"].dt.year : 년도
               df["Date"].dt.month : 월
               df["Date"].dt.day : 일
  형변환 : astype("자료형")   : str,int,float,category....     
  str : DataFrame의 요소들을 문자열처럼 사용. 문자열 함수 사용가능
              df["aaa"].str.startsWidth("")...     
  === 그룹화 : DataFrame을 분리기능
  groupby(컬럼명) : DataFrame 객체를 컬럼명의 값으로 분리.
  agg(함수)      : 지정한 함수를 적용할 수 있도록 하는 함수. 사용자정의함수 사용가능
  filter(조건함수) : 조건함수의 결과가 참인 경우인 데이터 추출
  === 병합 : 두개의 DataFrame 연결
  concat : 물리적을 연결
  merge  : 연결컬럼의 값을 기준으로 같은 값은 가진 레코드들을 연결
            merge(df1,df2,on="연결컬럼",how="outer/left/right")
'''
########## 1.BeautifulSoup : html,xml 태그 분석 모듈
from bs4 import BeautifulSoup
import urllib.request as req
url="https://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp"
res=req.urlopen(url) 
print(res) 
soup = BeautifulSoup(res,"html.parser")
title=soup.find("title").string # <title>태그의 내용
wf=soup.find("wf").string       # <wf>태그의 내용
print(title)
print(wf)

for w in wf.split("<br />") :
    print(w)

# 인터넷에서 수신된 내용을 forecast.xml 파일로 저장하기
import os.path
if not os.path.exists("data/forecast.xml") :
    req.urlretrieve(url,"data/forecast.xml")

#forecast.xml 파일을 읽어서 BeautifulSoup객체로 분석하기
fp = open("data/forecast.xml",encoding="utf-8")
soup = BeautifulSoup(fp,"html.parser") #파일을 읽어서 분석. DOM 객체의 루트노드 
#select_one : 태그 한개 선택 
#             rss 태그의 하위태그 중 pubDate 태그 선택
pubdate = soup.select_one("rss pubDate").string #선택된 태그의 내용
print(pubdate)

#select : 태그들.
rss = soup.select("rss")[0]  #rss 태그 중 첫번째 태그
pubdate = rss.select_one("pubDate").string
print(pubdate)

#모든 location 태그의 하위태그 중 city,wf 태그 하나의 내용를 조회하기
for location in soup.select("location") :
    name = location.select_one("city").string
    weather = location.select_one("wf").string
    print(name,weather)

#find_all("location") : location 태그 들
#find("city") : city 태그 한개
for location in soup.find_all("location") :
    name = location.find("city").string
    weather = location.find("wf").string
    print(name,weather)


### 네이버에 공시된 환율정보 출력하기
from bs4 import BeautifulSoup
import urllib.request as req
url = "https://finance.naver.com/marketindex/"
res = req.urlopen(url)
soup = BeautifulSoup (res,"html.parser",from_encoding="euc-kr")
sel = lambda q : soup.select(q)
#div.head_info : class속성이 head_info인 div 태그 들
hlist = sel("div.head_info")
print(hlist) #환율정보 표시해 주는 태그들
#h3.h_lst : class 속성이 h_lst인 h3 태그 들
htitle = sel("h3.h_lst")  #통화국가명
print(htitle)

taglist=[] #상승/하락 값
titlelist=[] #국가 통화명
#tag : 환율정보
#title : 국가명
for tag, title in zip(hlist, htitle) :
    print(title.select_one("span.blind").string, end="\t") #국가 통화명
    value = tag.select_one("span.value").string # 환율데이터
    print(value, end=" ")
    change = tag.select_one("span.change").string  #상승,하락 폭
    print(change, end="\t")
    blinds = tag.select("span.blind") #상승/하락 문자열
    b = tag.select("span.blind")[0].string #첫번째 요소 
    b = tag.select("span.blind")[-1].string #마지막 요소 
    print(b, end="*******\n")    
    print(blinds[-1].string, end="*******\n")    
    if b == '하락' :
       taglist.append(float(change) * -1) #하락인 경우 음수표시
    else :
       taglist.append(float(change)) #상승.
    titlelist.append(title.select_one("span.blind").string)

print(taglist)
print(titlelist)

titlelist = titlelist[:-1] #마지막 2개 데이터 제외
taglist = taglist[:-1]
print(taglist)
print(titlelist)


import matplotlib.pyplot as plt
from matplotlib import  rc
plt.style.use("ggplot")
plt.rcParams['axes.unicode_minus']=False
rc('font', family='Malgun Gothic')
xlab = range(len(titlelist)) #x축값. 0 ~ titlelist갯수-1까지
plt.bar(xlab,taglist)  #막대그래프. 
plt.plot(xlab,taglist) #선그래프. 
#xlab 데이터 => titlelist 수정. 세로로 표시
plt.xticks(xlab,titlelist,rotation='vertical') #x축 내용 설정.

########## 2. 셀레니움 예제 
#  인터넷의 내용을 조회. 실행 가능
'''
  chromedriver.exe 파일 다운 받기
  1. 크롬 브라우저 버전확인
     도움말 > 크롬정보 (버전 103.0.5060.66(공식 빌드) (64비트))
  2. http://chromedriver.chromium.org/downloads 연결
     => 크롬의 버전에 맞는 드라이버 다운받기
  3. 운영체제에 맞는 드라이버 다운 받기   
  4. 압축풀기     
  5. chromedriver.exe 파일의 위치 정하기 :c:/setup/
  
  =========================
  find_elements_by_css_selector : 오류 발생 : selenium-4.3.0 버전 오류발생
  1. pip uninstall selenium : selenium 설정 제거
  2. pip install selenium==3.141  : 3.141 버전의 selenium 설치
'''
from selenium import webdriver  #pip install selenium
import time
driver = webdriver.Chrome("c:/setup/chromedriver")
driver.get("http://python.org")
#css에서 사용되는 방법으로 #top ul.menu li
#   id=top 인태그의 하위 태그 중 class=menu인 ul 태그. ul 태그 하위의 li 태그 들
menus = driver.find_elements_by_css_selector('#top ul.menu li')
print(type(menus))
menus
pypi = None #값이 없다
#m : li태그 한개
for m in menus: 
    if m.text == "PyPI": #m태그의 문자열 내용
        pypi = m  #li 태그 
    print(m.tag_name,m.text)
pypi.click() 
time.sleep(5) #5초동안 대기
driver.quit() #브라우저 종료. 


### 네이버에 로그인 하기
driver = webdriver.Chrome("C:/setup/chromedriver")
driver.get("https://nid.naver.com/nidlogin.login?mode=form&url=https%3A%2F%2Fwww.naver.com")
id = input("네이버 아이디를 입력하세요:")
#execute_script : 자바스크립트 명령 실행.
#document.getElementsByName : name="id"인 태그들 선택
#document.getElementsByName('id')[0] : name="id"인 태그 중 첫번째 태그를 선택
#document.getElementsByName('id')[0].value : name="id"인 태그 중 첫번째 태그의 값
driver.execute_script("document.getElementsByName('id')[0].value='"+id+"'")
pw = input("네이버 비밀번호를 입력하세요 : ")
time.sleep(1) #1초 대기
driver.execute_script\
("document.getElementsByName('pw')[0].value='"+pw+"'")  #입력된 비밀번호 브라우저에 작성
time.sleep(1)
#find_element_by_xpath : xml에서 정의한 태그를 찾아가는 방식
'''
//*[@id="log.login"] : id속성이 log.login 인 태그 선택 => 로그인버튼선택

// : 루트노드.
*  : 모든 노드
[@id="log.login"] : @id= id속성의 값이 log.login 인 태그
'''
#.click() : 로그인 버튼 클릭.
driver.find_element_by_xpath('//*[@id="log.login"]').click()

# daum 페이지에서 이미지 다운받아 저장하기
from selenium import webdriver
import time
import urllib.request as req 
import os 
driver = webdriver.Chrome("c:/setup/chromedriver")
driver.get("https://search.daum.net/search?w=img&nil_search=btn&DA=NTB&enc=utf8&q=%ED%98%B8%EB%9E%91%EC%9D%B4" )
time.sleep(3)
#   #imgList > div > a > img
# id속성이 imgList인 태그의 하위태그 중 div 태그 하위태그의 
#  a 태그  그하위태그의 img 태그 들 
#images : img 태그 들.
images = driver.find_elements_by_css_selector("#imgList > div > a > img")
img_url = []
for image in images :
    #image : img 태그 한개
    #url : 이미지가 저장된 url 정보
    url = image.get_attribute('src') #src 속성의 값
    img_url.append(url)
print(img_url) #이미지가 저장된 url 목록
driver.quit()  #브라우저 닫기 

########## 3.이미지 다운 받기
img_folder = './img' 
if not os.path.isdir(img_folder) : #./img 폴더 존재하지 않으면
    os.mkdir(img_folder)  #폴더 생성

#enumerate(img_url) : index와 데이터로 나눠서 조회
for index, link in enumerate(img_url) :
    #index: 순서
    #link : 이미지 url
    #req.urlretrieve : 인터넷에서 제공되는 내용을 파일로 저장.
    #f'./img/{index}.jpg : 문자열 format형태 지정
    #                      {index} : index 변수이름의 값을 저장
	req.urlretrieve(link, f'./img/{index}.jpg') # f"./img/0.jpg"

#현재 화면을 이미지 파일로 저장하기
driver = webdriver.Chrome("c:/setup/chromedriver")
driver.get("https://search.daum.net/search?w=img&nil_search=btn&DA=NTB&enc=utf8&q=%ED%98%B8%EB%9E%91%EC%9D%B4")
driver.save_screenshot("img/tigerpage.png")
driver.quit()

############
#멕시코풍 프랜차이즈 chipotle의 주문 데이터
# chipotle.tsv : csv : 셀의 구분 ,
#                tsv : 셀의 구분 \t(탭). sep = '\t' 설정
############
import pandas as pd
#sep = '\t' : 셀의 구분 지정.
chipo = pd.read_csv("data/chipotle.tsv", sep = '\t')
chipo.info()
'''
데이터 속성 설명
order_id : 주문번호
quantity : 아이템의 주문수량
item_name : 주문한 아이템의 이름
choice_description : 주문한 아이템의 상세 선택 옵션
item_price : 주문 아이템의 가격 정보
'''
#chipo 데이터의 행열의 갯수 출력하기
chipo.shape
#chipo 처음 10건 출력하기
chipo.head(10)
#chipo 마지막 10건 출력하기
chipo.tail(10)

#column명, index를 조회하기
chipo.columns
chipo.index

# 통계값 조회하기. max,min,sum,mean,25%....
chipo.describe()
chipo.info()

# order_id 주문번호이므로, 숫자형 분석의 의미가 없다.
# order_id  컬럼의 자료형을 문자열로 변경하기
chipo["order_id"] = chipo["order_id"].astype(str)
chipo.info()

#판매상품명과 갯수 출력하기
print("판매상품명:")
print(chipo["item_name"].unique())
print("판매상품갯수 :",len(chipo["item_name"].unique()))

#item_name 별 가장 많이 주문한 상품이름 10개 출력하기
chipo["item_name"].value_counts()[:10]
chipo["item_name"].value_counts().index[:10]
728x90
반응형

'study > Python' 카테고리의 다른 글

[Python] 42. Test 답  (0) 2022.07.01
[Python] 42. Test  (0) 2022.07.01
[Python] 41. Test 답  (0) 2022.06.30
[Python] 41. Test  (0) 2022.06.30
[Python] 41. 데이터전처리, 날짜데이터처리, 주식데이터처리, BeautifulSoup  (0) 2022.06.30