오늘의 회고
- 사실(Fact) : 서울정보소통광장 120 데이터 수집하기 (목록, 내용)
- 느낌(Feeling) : 이해도가 조금 높아지니까 흥미가 더 생겨서 다른 페이지도 웹스크래핑에 도전해보고 싶어졌다.
- 교훈(Finding) : 오늘 수업 복습, 과제로 전체 데이터 가져와보는 것을 해봐야겠다.
멋사 AI스쿨 main lecture by 박조은 강사님
지난 주 복습
웹스크래핑은 requests로 수집하고 bs로 파싱하고 해석한다고 표현한다.
with 구문은 메모리를 할당 → 파일을 오픈할 때 주로 사용한다
로봇배제 표준 robot.txt
네트워크탭 Headers에서 get인지 post인지 확인 가능
프로그램을 구현하기 전에 과정을 정리해보는 단계가 중요하다.
팀플을 할 때도 이런 과정을 미리 공유해보고 시작하면 좋다.
프로그래밍 | 슈도코드 | pseudocode | 의사코드 | 순서도 -> 슈도코드 - RECOR:D
ex) 웹페이지에서 데이터를 가져오는 과정을 예측해보기
- 테이블 정보만 포함한 url 링크를 찾아 가져온다
- html 테이블태그를 이용해서 목록(번호, 제목, 생산일, 조회수)를 수집한다
- 페이지 반복문을 통해 전체 페이지의 목록을 가져온다
- href 주소도 담아둔다.
- 목록의 href주소의 끝의 8자리 숫자를 상세 페이지 번호로 가져온다
- 본문의 문서 정보 테이블도 가져온다.
- 상세 페이지 번호를 변수로 이용해서 전체 정보를 가져온다(parameter에 argument 넣는 작업)
- 가져온 정보를 목록 + 본문으로 데이터프레임 형태로 연결한다
서울시 다산콜센터 주요민원 정보 웹 스크랩핑
메인 테이블 정보 수집하기
라이브러리 불러오기
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup as bs
import requests
import time
URL 링크의 table 정보 가져오기
# pd.read_html 을 통해 해당 URL의 table 정보를 읽어옵니다.
table = pd.read_html(base_url, encoding = "utf-8")
# 글자가 꺠지면 encoding 추가 uf-8, cp949 둘 중 하나
table[0]
상세 정보를 수집할때 requests 활용
응답 코드확인: .status_code 200이 나오면 OK
특정 페이지 목록을 수집하는 함수로 만들어서 활용
def get_one_page(page_no):
"""
120 주요질문의 특정 페이지 목록을 수집
"""
# 1) page_no 마다 url이 변경되게 f-string 을 사용해 만든다.
base_url = f"<https://opengov.seoul.go.kr/civilappeal/list?items_per_page=50&page={page_no}>"
# 2) requests 를 사용해서 요청을 보내고 응답을 받는다.
response = requests.get(base_url)
# 3) pd.read_html을 사용해서 table tag로 게시물을 읽어온다.
# 4) 3번 결과에서 0번 인덱스를 가져와 데이터프레임으로 목록의 내용을 만든다.
table = pd.read_html(response.text)[0]
# 5) html tag를 parsing할 수 있게 bs 형태로 만든다.
html = bs(response.text)
# 6) 목록 안에 있는 a tag를 찾는다.
a_list = html.select("td.data-title.aLeft > a")
# 7) a tag 안에서 string 을 분리해서 내용번호만 리스트 형태로 만든다.
# 8) 4)의 결과에 "내용번호"라는 컬럼을 만들고 a tag의 리스트를 추가한다.
table["내용번호"] = [a_tag["href"].split("/")[-1] for a_tag in a_list]
return table
try except 구문 → 예외 처리
- return 안내 문구 또는 raise Exception()으로 오류 발생시키기
반복문을 통한 여러 페이지 수집하기
반복을 빠져나가는 조건을 무엇으로 할 것인지 정하는 것이 중요하다.
while문 멈추는 조건
return 값의 타입이 str이면 멈추기
df_temp.shape[0] == 0로 쓸 수없는 이유는?
attribute error가 발생, 오류 메시지는 str타입
# time.sleep을 통해 일정 간격 쉬었다가 가져옵니다.
# 게시물이 없으면 멈춥니다.
page_no = 1
table_list = []
while True:
print(page_no, end=",")
df_temp = get_one_page(page_no)
if type(df_temp) == str : #오류메시지는 str이라서 조건
print("수집이 완료되었습니다.")
break
table_list.append(df_temp)
page_no += 1
time.sleep(0.01)
데이터 병합하기 pd.concat(table_list)
파일 저장하기 df.to_csv(file_name, index=False)
각 페이지의 상세 정보 수집하기
SELECTOR 사용
html.select("#content > div > div.view-content.view-content-article > div > div.line-all")
#content > div > div.view-content.view-content-article > div:nth-child(2) > div
selector 가져올때 class가 복사가 안되면 .찍고 직접 입력해도된다
텍스트만 가져오기
.get_text()
.text
2X3 테이블을 1X6으로 펼치는법
1) 전치행렬 활용
2) index맞춤
3) pd.concat활용 axis=1