연설문 목록 스크래핑
- 수집하고자 하는 대상의 URL 을 알아봅니다.
- 사이트에 접속한다. => HTTP 요청을 보냅니다. requests
- 목록을 받아온다. (번호, 대통령, 형태, 유형, 제목, 연설일자) + BautifulSoup을 통해 내용의 링크도 함께 수집
- 3번을 반복해서 전체 데이터를 수집한다.
- 파일로 저장한다.
연설문 목록에 URL 추가
- 0105에서 저장한 대통령 연설문 목록을 가져옵니다.
- 내용링크를 통해 각 연설문의 내용 링크에 요청을 보냅니다.
- BeautifulSoup을 통해 내용을 찾아옵니다.
- 내용의 링크를 통해 내용을 찾는 함수를 만듭니다.
- 전체 게시물에 내용을 찾는 함수를 적용합니다. => 반복문을 사용하지 않고 Pandas 의 map, apply 등의 기능을 사용할 예정입니다.
- 수집이 되면 내용 파생변수를 생성해 줍니다.
- 저장합니다.
# requests, bs4, pandas 불러오기
import requests
from bs4 import BeautifulSoup as bs
import pandas as pd
table 형식이니까 pd.read_html 해볼까? -> 오류 생김
why? 인증서 오류가 남 + post 방식
대통 기록관 수집은 이전 수집했던 네이버 금융 뉴스와 일별 시세 어떤 차이 있을까?
- 대통령 기록관은 post방식 -> 바로 requests 보내면 응답 x
- ssl 인증서 사용하고 있음 -> ssl 오류가 남 -> verify = False 해서 해결
headers = {"User-Agent": "",
"Referer": "",
"Content-Type": "",}
headers # 왜 안 넣는거지?
이번에는 headers 필요 x
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
얘도 하는데 인증서가 없는 사이트에서 접속시에 에러메시지가 발생 -> verify = False는 인증서 확인 과정을 생략하겠다는 의미인데 인증서가 없는 사이트 접속으로 인해 혹시라도 발생할 수 있는 문제를 알려주기 위한 경고 메시지 -> 이 경고 메시지 보기 싫으면 비활성화 하려고 사용하는 코드
# URL 만들기
page_no = 70
url = "https://www.pa.go.kr/research/contents/speech/index.jsp"
params = f"spMode=&artid=&catid=&pageIndex={page_no}&searchHistoryCount=0&searchStartDate=&searchEndDate=&pageUnit=20"
response = requests.post(url, params = params, verify = False)
이 페이지는 페이지 넘어갈 때 마다 url이 변하지 않음 페이지 넘기는 것을 params 지정해서 나타내야 함
여기서 찾을 수 있음
pd.read_html(response.text)[0]
pd.read_html(response.text) 하는 이유는? bs 안 하고 그냥 정말 너무 많고 헷갈려서 바로 pd로
마지막 페이지 찾기 -> BeautifulSoup 사용
bs 사용하는 이유는 조금더 깔끔하게 보기 위해서
html = bs(response.text) # 어떤 페이지가 마지막 페이지인지 찾기 위해
# find_all 로 찾기
html.find_all('a', {'class' : 'last'})[0]['href'].split('=')[-1]
# select 로 찾기 a 넣는 이유는 href가 a 태그의 속성이라
last_page = html.select('nav.board-paging > ul > li > a')[-1]['href'].split('=')[-1]
last_page = int(last_page)
last_page
이런 방식으로 마지막 페이지 찾으면 반복문 작성할 때 마지막 페이지까지 반복할 수 있도록 작성할 수 있음
frm > nav.board-paging.space5 > ul > li:nth-child(14) > a 찾는 방법은 마지막 페이지 누르고 검사 -> select copy
df = pd.read_html(response.text)
df #리스트 형식으로
df = pd.read_html(response.text)[0]
df
df로 만들어줌
여기까지 대통령 연설문 목록 가져오는 방법
연설문 목록에 URL 추가
- 0105에서 저장한 대통령 연설문 목록을 가져옵니다.
- 내용링크를 통해 각 연설문의 내용 링크에 요청을 보냅니다.
- BeautifulSoup을 통해 내용을 찾아옵니다.
- 내용의 링크를 통해 내용을 찾는 함수를 만듭니다.
- 전체 게시물에 내용을 찾는 함수를 적용합니다. => 반복문을 사용하지 않고 Pandas 의 map, apply 등의 기능을 사용할 예정입니다.
- 수집이 되면 내용 파생변수를 생성해 줍니다.
- 저장합니다.
내용링크를 찾는 방법
내용 검사 -> 네트워크 -> a태그 통해 링크 알 수 있음 (어떻게 생겼나 알 수 있음)
그 다음 할 일은? selector로 복사 -> bs로 select, find, find_all 사용해서 a태그 찾기
selector copy로 알아낸 것
html = bs(response.text)
# .select() 로 해당 a 태그 찾기
html.select('#M_More > tr > td.subject > a')
html.find_all('td', {'class' : 'subject'})
이 방법도 있음
a tag 찾기
# a tag 찾기
print(html.select('#M_More > tr > td.subject > a')[0]['href'])
print(html.select('#M_More > tr > td.subject > a')[1]['href'])
href list 만들기
정말 리스트에 담기 위한 과정임
a_href = []
for i in html.select('#M_More > tr > td.subject > a') :
a_href.append(i['href'])#href하면 링크만 뽑아올 수 있음
a_href
# 방법 2
a_href = []
for i in range(len(html.select('#M_More > tr > td.subject > a'))) :
a_href.append(html.select('#M_More > tr > td.subject > a')[i]['href'])
a_href
# 방법 3
a_href = []
for i, val in enumerate(html.select('#M_More > tr > td.subject > a')) :
a_href.append(val['href'])
a_href
# 방법 4 : 리스트 컴프리헨션(리스트 함축)
a_href = [a['href'] for a in html.select('#M_More > tr > td.subject > a')]
a_href
내용링크 파생변수 만들기
# "내용링크" 파생변수 만들기
df["내용링크"] = a_href
df.head(2)
전체 과정 함수로
def page_scrapping(page_no):
"""
1) page 번호로 URL 만들기
2) requests.post()로 요청하기
3) bs 적용
4) 테이블 찾기
5) a 태그 목록 찾기
6) 내용링크에 a 태그 주소 추가하기
7) 데이터프레임 반환
"""
url = "https://www.pa.go.kr/research/contents/speech/index.jsp?"
params = f"spMode=&artid=&catid=&pageIndex={page_no}&searchHistoryCount=0&pageUnit=20"
response = requests.post(url=url, params=params, verify=False)
html = bs(response.text)
df_table = pd.read_html(response.text)[0]
df_table["내용링크"] = [ a["href"] for a in html.select("#M_More > tr > td.subject > a") ]
return df_table
# 함수가 잘 동작하는지 확인
page_scrapping(page_no=3)
# 함수 잘 작동하는지 확인 2
i = 3
print(df_table["제목"][i])
print(url + df_table["내용링크"][i])
마지막 페이지까지 연설 목록 가져오고 링크까지!
from tqdm import trange
import time
# 경고메시지가 있으면 tqdm 로그가 너무 많이 찍히기 때문에 경고메시지를 제거합니다.
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
page_list = []
for page_no in trange(1, last_page + 1) :
result = page_scrapping(page_no)
page_list.append(result)
time.sleep(0.001)
pd.concat(page_list)
'AI SCHOOL > Python' 카테고리의 다른 글
[Python] 대통령연설기록 수집 - 2 (연설 내 가져오기) (0) | 2023.01.22 |
---|---|
[Python] 다산콜센터 주요 민원 목록 수집(1) (0) | 2023.01.19 |
[Python] 네이버 금융 뉴스기사 수집 (0) | 2023.01.15 |
[Python] FinanceDataReader (0) | 2023.01.12 |
[Python] pandas 기초 (0) | 2023.01.12 |