본문 바로가기
Study/Data전처리 및 통계

Pandas(3)

by 왕방개 2024. 2. 13.

**데이터 수집

1.검색어를 입력받아서 신문 기사를 스크램핑해서 파일에 저장하기

 

1) 필요한 패키지

=>request:검색어가 한글이라면 인코딩을 하기 위해서

=>requests:웹의 문자열을 읽어오기 위한 패키지, 기본 패키지가 아니라 설치 해야함

=>beautifulsoup:HTML 문자열에서 원하는 데이터를 추출하기 위해서 필요한 패키지, 기본 패키지가 아니라서 설치를 해야함

 

2)URL확인

https://www.donga.com/news/search?query=%EC%9C%A0%EC%9E%AC%EC%84%9D&sorting=1&check_news=91&search_date=1&v1=&v2=&more=1 

=>query:검색어

=>sorting,check_news,search_date

 

3)URL 확인을 통해서 targetURL을 변경

from urllib.parse import quote

#검색어를 받아서 인코딩
string=input("검색어를 입력하세요:")
keyword=quote(string)
#print(keyword) =>인코딩된 결과가 나옴

target_URL="https://www.donga.com/news/search?query={}&sorting=1&check_news=91&search_date=1&v1=&v2=&more=1".format(keyword)

 

 

4)검색어를 입력받아서 URL 만들기

import requests
html=requests.get(target_URL).text
print(html)

 

5)기사 개수를 가져오기

#HTML 파싱에 사용하는 패키지
from bs4 import BeautifulSoup
#HTML 텍스트는 메모리에 트리 형태로 펼치기

bs=BeautifulSoup(html,'html.parser')

#선택자는 동일한 데이터가 있을 수 있으므로 list
cnt=bs.select('div.cntPage > span')
#데이터가하나 뿐이라 반복문은 안돌림
'''
for x in cnt:
    print(x.getText())
'''
cnt=cnt[0].getText()
cnt=int(cnt[0:-1])
print(cnt)

 

6)기사 링크 가져오기

#페이지 개수 만들기
import math

pageno=math.ceil(cnt/15)#올림

#기사의 링크를 저장할 LIST
links=[]
#페이지 개수만큼 순회함녀서 html을 읽어서 파싱해서 저장
for i in range(0,pageno):
    #기사 링크와 제목이 나오는 페이지를 읽기
    url="https://www.donga.com/news/search?p={}&query={}&sorting=1&check_news=91&search_date=1&v1=&v2=&more=1".format(i*15+1,keyword)
    html=requests.get(url).text
    soup=BeautifulSoup(html,"html.parser")
    linktag = bs.select('span.tit > a')

    for tag in linktag:
        #a 태그에 href 속성의 값을 가져오기
        links.append(tag['href'])

print(links)

 

 

7)기사 링크에 가서 기사를 읽어서 텍스트로 저장

#텍스트 파일을 생성
output_file=open(string+".txt","w",encoding="utf-8")

for link in links:
    html=requests.get(link).text
    bs=BeautifulSoup(html,"html.parser")
    articles=bs.select("#article_txt")
    for article in articles:
        article.getText()
        #파일에 기록
        output_file.write(article.getText())

output_file.close()

 

 

2.Selenium

 

1)개요

=>웹 앱을 테스트하는데 사용하는 프레임워크

=>WebDriver 라는 API를 이용해서 운영체제에 설치된 브라우저를 제어하는 프레임워크

=>크롤링할 때 JavaScript을 이용해서 비동기적으로 가져오는 데이터를 읽고자 할 때 이용할 수 있고 로그인 후 가져와야 하는 데이터를 읽어오는데 사용합니다

=>메뉴얼:http://docs.selenium.org/docs/

2) 크롬 브라우저 실행

=>파이썬에서 사용 준비

패키지 설치:pip install selenium

 

브라우저의 드라이버가 필요

=>chrome driver 다운로드 검색후 맞는 버전 다운로드

 

 

3)크롬 실행 실습

from selenium import webdriver
import os

os.environ['webdriver.chrome.driver']='다운받은 크롬 경로'
driver=webdriver.Chrome()
while(True):
    pass

 

4)기본 API
=>접속:get(url)

=>html 코드 가져오기:page_source

=>일정시간대기:implicit_wait(시간)

=>브라우저 종료:quit()

from selenium import webdriver
import os

#드라이버 경로 설정
os.environ['webdriver.chrome.driver']='C:\\Users\\User\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver=webdriver.Chrome()
#사이트 접속
driver.get("https://www.kakao.com")
html=driver.page_source
print(html)
while(True):
    pass

 

5)element 접근 API

=>하나만 찾는 API

find_element_by_name(이름)

find_element_by_id(아이디)

find_element_by_xpath(xpath)

 

=>배열로 찾는 API

find_element_by_css_selector(선택자)

find_element_by_css_class_name(클래스 이름)

find_element_by_tag_name(태그)

 

6)Element 동작 API

send_keys(값):값이 입력됨

click(),submit():클릭

 

7)스크립트 실행

execute_script(스크립트 코드)

 

8)카카오 자동 로그인

=>카카오 로그인 사이트: https://accounts.kakao.com/login/?continue=https%3A%2F%2Faccounts.kakao.com%2Fweblogin%2Faccount#login

from selenium import webdriver
from selenium.webdriver.common.by import By
import os

#드라이버 경로 설정
os.environ['webdriver.chrome.driver']='C:\\Users\\User\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver=webdriver.Chrome()
#카카오 로그인사이트 접속
driver.get("https://accounts.kakao.com/login/?continue=https%3A%2F%2Faccounts.kakao.com%2Fweblogin%2Faccount#login")
#5초간 대기
driver.implicitly_wait(5)

userid=input("아이디")
password=input("비밀번호")

driver.find_element(By.XPATH,'//*[@id="loginId--1"]').send_keys(userid)
driver.find_element(By.XPATH,'//*[@id="password--2"]').send_keys(password)
driver.find_element(By.XPATH,'//*[@id="mainContent"]/div/div/form/div[4]/button[1]').click()


while(True):
    pass

 

 

9)스크롤(자바스크립트 수행)을 하면서 데이터를 수집=>무한스크롤

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import bs4
import os
import time

#드라이버 경로 설정
os.environ['webdriver.chrome.driver']='C:\\Users\\User\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver=webdriver.Chrome()
#카카오 로그인사이트 접속
driver.get("https://www.youtube.com/results?search_query=%EB%89%B4%EC%A7%84%EC%8A%A4")
#5초간 대기
time.sleep(5)

second=0

body=driver.find_element(By.TAG_NAME,'body')
while second<10:
    body.send_keys(Keys.PAGE_DOWN)
    time.sleep(2)
    second=second+1



while(True):
    pass

 

10)네이버 로그인

위에 카카오 로그인을 헀을때 로봇이 아닙니다 같은 문구가 뜨면서 로그인에 방해가 됨

=>아이디와 비밀번호를 입력했을 때 capture가 보이는 경우는 입력을 직접하지 않고 자바스크립트를 이용하여 로그인

from selenium import webdriver
from selenium.webdriver.common.by import By
import os

#드라이버 경로 설정
os.environ['webdriver.chrome.driver']='C:\\Users\\User\\Downloads\\chromedriver-win64\\chromedriver-win64\\chromedriver'
driver=webdriver.Chrome()
#카카오 로그인사이트 접속
driver.get("https://nid.naver.com/nidlogin.login")
#5초간 대기
driver.implicitly_wait(5)

userid=input("아이디")
password=input("비밀번호")

driver.execute_script("document.getElementsByName('id')[0].value=\'"+userid+"\'")
driver.execute_script("document.getElementsByName('pw')[0].value=\'"+password+"\'")
driver.find_element(By.XPATH,'//*[@id="log.login"]').click()
                      

while(True):
    pass

 

3.MySQL의 데이터를 가져와서 DataFrame 만들기

1)필요한 패키지

=>sqlalchemy

=>pymysql

 

2)데이터베이스 연결

from sqlalchemy import create_engine

database_connection=create_engine('데이터베이스 접속 URL')

#데이터베이스 접속 URL은 데이터베이스 종류마다 다름
#별도의 패키지를 설치해야하는 경우가 있음  ex.)pymysql
#url은 데이터베이스종류://아이디:비밀번호@IP:포트(3306이면생략가능)/데이터베이스이름

 

3)테이블 가져와서 DataFrame 만들기

dataframe=pandas.read_sql_table('테이블이름',database_connection)

 

4)실습

=>샘플데이터 생성

use bkbk;

create table sampledata(
	num int(10)NOT NULL AUTO_INCREMENT,
	name varchar(255) NOT NULL,
	vendor varchar(255)NOT NULL,
	description varchar(255),
	PRIMARY KEY(num));
    
    
INSERT INTO sampledata(name,vendor,description)
values('Oracle','Oracle','금융과 대기업에서 많이 사용하는 가장 안정적인 데이터베이스');

INSERT INTO sampledata(name,vendor,description)
values('HANADB','SAP','오라클 대체용으로 사용하는 데이터베이스로 현대자동차에서 사용');

INSERT INTO sampledata(name,vendor,description)
values('MySQL','Oracle','현재 가장 많이 사용한다고 알려진 관계형 데이터베이스로 플랫폼기업에서 사용');

INSERT INTO sampledata(name,vendor,description)
values('MariaDB','OpenSource','MySQL의 fork로 현재는 카카오에서 사용중');

INSERT INTO sampledata(name,vendor,description)
values('PostgreSQL','OpenSource','최근들어 많이 사용되는 데이터베이스');

 

=>python 에서 database 불러와서 사용하기

from sqlalchemy import create_engine
import pandas as pd
import pymysql

database_connection=create_engine('데이터베이스URL')
df=pd.read_sql_table('sampledata',database_connection)
print(df)

 

4.그 이외의 데이터 사용

 

1)R의 데이터 활용

=>pyreadr이라는 패키지를 사용

=>읽는 방법

pyreadr.readr('rds 파일 경로')[None]

 

2)통계 프로그램 데이터 읽어오기

=>pyreadstat 패키지를 이용하면 SPSS,Stata,SAS 프로그램의 데이터를 읽을 수 있음

참고로 데이터 분석은 위 프로그램이 더 빠르지만, 얘네는 회사 프로그램이다보니 업데이트 속도를 맞출수가 없음

파이썬은 opensource로 누구나 사용가능하게 해놔서 더 좋음

 

3)최근 데이터 분석을 할 때 pandas 의 DataFrame을 이용하지 않고 pySpark의 dataframe을 이용하는 경우가 많은데 이 이유 중 하나는 pySpark가 가져올 수 있는 데이터의 종류가 더 많기 떄문입니다.

pySpark에서도 SQL 그대로 사용가능하기 때문에 SQL을 아는 것은 중요합니다.

 


**데이터 탐색

 

1.데이터 프레임에서의 데이터 선택

1)열 선택

=>데이터프레임['컬럼이름'] 또는 데이터프레임.컬럼이름

=>데이터프레임.컬럼이름 으로 접근할 때는 컬럼이름이 반드시 문자열이어야 합니다

=>하나의 컬럼이름을 이용해서 접근하면  Series 로 리턴

 

2)행 선택

=>loc[인덱스이름]으로 접근

=>iloc[정수형 위치 인덱스]로 접근

=>Series로 리턴

 

3)셀 선택

=>[컬럼이름][인덱스이름]의 형태로 접근

=>loc[인덱스이름,컬럼이름]

=>iloc[행 위치 인덱스,열 위치 인덱스]

 

4)다중 선택

=>list을 이용해서 선택하면 됩니다.

=>list 을 이용해서 선택을 하면 DataFrame이 리턴됩니다.

 

csv읽을 때 확인할 3가지
1.한글 포함 여부 - 인코딩
2.구분자가 무엇인지- 기본은 ,(comma)
3.첫번째 줄이 컬럼이름인지 아니면 데이터인지
추가적으로 컬럼 중에 primary key의 역할을 할 수 있는게 있는지 확인하는게 좋음

 5)실습

=>사용중인 컬럼을 인덱스로 활용

#현재 사용중인 컬럼을 인덱스로 활용
df.index=df['code']
print(df)

 

=>열 하나를 선택

print(df["name"]) #type이 Series
print(df.name)
print(df[["name"]]) #열을 선택할 떄 list 을 이용 - DataFrame으로 리턴

 

=>열 여러개를 선택

#여러 열을 선택
print(df[['name','price']])

 

=>행을 하나 선택

#행선택
print(df.iloc[0]) #0번째 행
print(df.loc[1])

 

=>셀을 선택

print(df['name'][2]) #name 컬럼의 3번째 데이터

 

6)범위를 이용한 행 인덱싱

=>[시작위치:종료위치:간격]을 이용하는 것이 가능

시작위치 생략하면 0, 종료 위치 생략하면 마지막,간격을 생략하면 1

종료위치지만 실제로는 종료위치 앞까지 슬라이싱

위치 인덱스 대신에 인덱스 이름을 이용하는 것도 가능한데 이 경우는 종료위치가 포함됩니다.

print(df.iloc[0:5:2]) #위치 인덱스에서는 마지막 위치가 포함되지 않음
print(df.loc[1:5:2]) #이름 인덱스 에서는 마지막 위치가 포함됨

 

7)Boolean 인덱싱

=>bool 타입의 Series을 대입하면 True인 행 만 선택

=>Series 객체 비교연산자 값 이용하면 bool 타입의 Series을 리턴

df['price']>3000

=>& 와 |을 이용한 결합도 가능

print(df[(df['price']<=1500) & (df['price']>=1000)])

=>isin([데이터나열]):데이터 안에 속하면  True 그렇지 않으면 False 를 리턴

print(df[df['price'].isin([1000,500])])

2.내용 확인

1)head 와 tail

=>DataFrame의 데이터 중에서 앞이나 뒤에서  몇 개의 데이터를 확인하고자 할 때 사용

 

2)shape:행과 열의 개수를 tuple 형식으로 리턴

 

3)info(): DataFrame의 기본 정보를 리턴하는 함수

데이터 유형

행 인덱스의 구성

열 이름

각 열의 자료형과 데이터 개수

메모리 사용량

 

4)dtypes: 각 열의 자료형 정보를 리턴

 

5)count:데이터의 개수

 

6)value_counts(): Series에서만 사용이 가능한데 고유한 값의 종류와 개수 정보

 

7)describe():기술 통계 정보를 출력

옵션이 없으면 숫자 데이터의 평균, 표준편차, 최대,최소,중간값

include='all'옵션으로 추가하면 숫자 데이터가 아닌 열의 unique, top, freq 를 출력

 

8)실습:auto-mpg.csv파일의 데이터 확인

=>자동차 연비와 관련된 데이터셋으로 회귀에 사용

=>컬럼

msg

cylinders

displacement

horsepower

weight

acceleration

model_year

origin

name

car=pd.read_csv('data (2)/data/noheader_auto-mpg.csv')
#칼럼을 직접 설정
car.columns=['mpg','cylinders','displacement','horsepower','weight','acceleration','model_year','origin','name']
#처음 5개 데이터만 확인
print(car.head())
print(car.describe())
print(car.dtypes)
print(car.count())

#앞의 3가지 정보를 전부 확인 가능하고 null(None)도 확인 가능
car.info()
#값의 개수와 빈도 수를 확인
print(car['cylinders'].value_counts())

 

 

'Study > Data전처리 및 통계' 카테고리의 다른 글

Pandas(5)  (0) 2024.02.15
Pandas(4)  (0) 2024.02.14
Pandas(2)  (0) 2024.02.08
Pandas(1)  (0) 2024.02.07
Numpy(2)  (0) 2024.02.07