본문 바로가기
Python/멋사_AIS7

Day 14

by Hi_heidi 2022. 10. 4.

Day 14

url알아보기

네트워크 > XHR/JS/Doc > Headers 에서 원하는 URL을 찾을 수 있다

pd.read_html(url) #urltable정보를 읽어온다
pd.read_html(url, encoding="utf-8") #한글이 깨질 때는 인코딩을 직접 기입한다 (또는 cp949)

링크 정보 수집

1. GET방식과 POST방식

get과 post방식은 모두 브라우저가 서버에 요청하는 것이다. 네트워크 > Js > Headers > Request Method에서 확인할 수 있다.

  • GET : 필요한 데이터를 Query String에 담아 전송한다. 쿼리 스트링은 URL의 끝에 ?와 함께 이름과 값으로 쌍을 이루는 요청 파라미터를 말한다. 만일 요청 파라미터라 여러개면 &로 연결한다.
    • 예시) 네이버 웹툰 <독립일기> 3페이지 링크 중 webtoon/list?titleId=748105&weekday=thu&page=3
    • 네트워크 > JS > payload 로 가면 query string parameter라고 확인 가능
    • 특징) ㉮브라우저의 히스토리에 남고 ㉯길이 제한이 있다. ㉰보안 문제 때문에(url에 정보가 노출됨) 중요한 정보를 다루는 것을 지양한다고 한다.
  • POST : 전송할 데이터를 HTTP 메시지 body의 Form Data에 담아 전송한다. 리소스 생성 및 변경을 위해 만들어졌다. 회원 가입할 때 적은 정보 폼, 물건이나 음식을 주문할 때 메시지를 입력하고 버튼을 누를 때 주로 사용한다.
    • header에 body(요청 데이터)의 콘텐츠 타입을 명시하는 Content-Type 헤더를 포함해야 한다.
    • 네트워크 > XHR > Payload로 가면 Form Data라고 확인 가능
    • 특징) ㉮브라우저의 히스토리에 남지 않고 ㉯길이 제한이 없다. ㉰url에 정보가 노출되지 않아 상대적으로 보안적이다.

2. requests로 수집

response = requests.get(url) #웹페이지의 결과를 받아온다

-상세정보(링크) 수집을 위해서는 requests를 써야 한다

-인코딩 기능이 내재한다

response.status_code #응답코드를 확인할 수 있다

200 == ok. 오류 없이 정상 응답했다

BeautifulSoup으로 html 읽기 쉽게 만들기

뷰티풀숩은 읽어온 사이트의 html문서를 해석하려는 목적으로 사용한다. 데이터 수집 도구가 아니며 html을 보기 좋게 parsing해준다.

html = bs(response.text) #bs로 수집한 html문서에서 링크 정보를 찾는다

-json은 뷰티풀숩을 사용할 필요가 없다고 한다

링크 정보 찾기

1. find_all과 select

더보기

https://www.crummy.com/software/BeautifulSoup/bs4/doc.ko/ 뷰티풀숩 공식 문서 참고

find_all과 select는 모두 특정 태그를 찾는데 사용하는 함수다.

soup.find_all('a')

-전체 문서를 훑어서 결과를 찾고 모든 a태그를 찾아준다.

-메뉴, 페이징 등 모든 a태그가 있는 정보가 추출돼 전처리가 복잡해진다.

soup.find_all("a", class_="sister")
soup.find_all("a", "sister") #2번째 인자는 attrs인데 문자열을 쓰면 class처럼 탐색한다

class 지정도 가능하다

  • select()
soup.select('td.data-title.aLeft > a')

-네트워크 탭에서 copy selector한 후 필요한 링크만 남겨 select함수를 적용할 수 있다.

-원래 링크에는 tr:nth-child(3)이런 코드도 있었는데 이는 순서에 관한 정보라 지워줘야 한다.

soup.select(".sister") #class로 태그를 찾는다
soup.select("#link1") #id로 태그를 찾는다

-다른 태그 바로 아래에 있는 태그를 찾을 수 있어 편리하다

-find_all보다는 select를 추천하셨다

2. 글번호 가져오기

a_list = html.select("td.data-title.aLeft > a")
a_list[1]['href'] #링크 정보 중 글번호 숫자까지 가져오기
a_list[1]['href'].split("/")[-1] #글번호 위해 '/'기준으로 문자열 슬라이싱 후 마지막 값 가져오기

#for문에 넣어 글번호 가져오기 반복
a_link_no = []
for a_tag in a_list:
    a_link_no.append(a_tag['href'].split("/")[-1])

a_link_no = [a_tag['href'].split("/")[-1] for a_tag in a_list] #리스트 컴프리헨션으로 간단하게 만들어줄 수 있다

3. 컬럼 생성

table[0]["글번호"] = a_link_no #df의 마지막 컬럼으로 생성됨

데이터 프레임 합치기(1) : 전치행렬

table[[0,1]].set_index(0).T
#테이블의 [0]열과 [1]열을 가공한다
#set_index(0) [0]열을 인덱스 형태로 만들어준다
#.T == transpose() 전치행렬, 행과 열을 교환한다

table[[2,3]].set_index(2).T
#테이블의 [2]열과 [3]열을 가공한다
#set_index(2) [2]열을 인덱스 형태로 만들어준다
#.T == transpose() 전치행렬, 행과 열을 교환한다

데이터 프레임 합치기(2) : concat, merge, join

더보기

0301 실습파일 이미지 참고하기

아래의 파라미터들은 디폴트값이다.

1. concat()

pandas cheat sheet

pd.concat([df1,df2], axis=1)
#axis=0 (행 기준, 디폴트)상하로 이어붙이기 axis=1 (열 기준)좌우로 이어붙이기

2. merge()

pandas cheat sheet

pd.merge(df_left, df_right, how='inner', on=None)
#df_left 왼쪽에 위치할 df
#df_right 오른쪽에 위치할 df
#how='inner' 교집합(두 df 고유값의 교집합을 기준으로 병합)
#on=None 아무 옵션을 지정하지 않겠다(어떤 옵션이 가능한 지는 나중에 찾아보자)

-merge는 어떤 키(컬럼?)가 기준이 되는지 지정해줘야 한다

-만일 3개 이상의 dataframe을 합치고 싶으면 2개씩 merge해줘야 한다

3. join()

df1.join(df2. how='left')
#df1이 왼쪽, df2가 오른쪽에 위치하게 됨
#how='left' 행 인덱스를 기준으로 결합

기타

  • 수도코드(pseudocode) 세우기 : 코드를 짜기 전 알고리즘을 설계해 보는 것. 진행 상황을 글로 써 놓으면 코드를 짜기 수월하고 타인이 이해하기가 쉽다. 목표와 방법을 공유해 협업을 원활하게 해주기도 한다.
  • table.shape[0]은 데이터 프레임의 행의 갯수, table.shape[1]은 데이터 프레임의 열의 갯수
  • try - except 구문 : 오류가 나더라도 실행을 지속한다.
  • raise Exception(f"{page_no}페이지를 찾을 수 없습니다.") 실행은 계속하고 예외 메시지만 출력하도록 하는 방법
  • soup.get_text() 뷰티플숩 함수. 텍스트만 가져온다
  • type( ) 타입(str, int, float) 확인
  • pd.concat( ) 데이터 병합

출처) 멋쟁이 사자처럼 AI스쿨 7기 박조은 강사님 강의자료

'Python > 멋사_AIS7' 카테고리의 다른 글

Day 16  (0) 2022.10.06
Day 15  (0) 2022.10.06
Day 12~13  (0) 2022.10.04
Day 10  (0) 2022.09.27
Day 09  (0) 2022.09.27