저번 포스팅에서 셀레니움을 이용해서, 필요한 frame으로 이동하고~ 원하는 버튼 클릭하고
보이는 화면의 데이터들을 수집하고, 필터링하는 방법에 대해 알아보았는데요
https://rogios-story.tistory.com/entry/selenium-g2b-Crawling-2-4 (저번 포스팅)
이번 포스팅에서는 requests를 이용해서 조금 더 빠르고 쉽게 진행해 보도록 하겠습니다.
현재 화면에서, 원하는 내용을 설정하고, '검색' 버튼을 누르면
아래 결과가 쭈욱~ 나타나는데요? ㅎㅎ
검색 버튼을 누르기 전으로 돌아가서, 네트워크를 열고 검색 버튼을 눌러보겠습니다!
(검색 버튼을 눌렀을 때, 어떤 네트워크 로그들이 남는지 확인하려는 거예요~)
두 번째로 나타난 저 tbidLIst라는 게 조금 수상하죠? 이름에도 list가 들어간 모습이...
우리가 보고 싶은 목록이 보일 것 같은 느낌이 오시나요?
네트워크의 preview를 눌러보시면 비록, 한글이 깨져서 나오지만, 우리가 보고 싶은 모습이 그대로 담겨있을 것 같은 느낌이 더 들어요!!
그럼 일단 저 친구를 파이썬에서 불러서 확인해 봐야겠어요! ㅎㅎ
제 방법을 따라 해 보세요
파이썬으로 requests 라이브러리 이용해서 데이터 불러오는 방법
1. Headers 탭에서 Request Method 방법 알아오기
먼저 헤더스 텝에서, requests 방법을 어떤 걸 쓰는지 확인해야 해요, 이번 포스팅에서는 GET 방식을 이용했네요
참고로 request 방식에는 GET 방식과 POST 방식이 있습니다
2. payload 검토하기
GET 방식인 경우에는, POST 방식보다 훨씬 편하게 payload를 확인할 수 있어요
저는 혹시 몰라서 url을 새 탭에 불러와보기도 했습니다
그다음 payload를 살펴보아요
3. headers 복사하기
Headers 탭에서, Request Headers 내용을 모두 복사해서 변수에 넣어줄 예정이에요
4. 파이썬에서 requests 코드 작성하기
아래와 같은 코드가 나오는데요
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 29 21:12:23 2023
@author: 진연녹
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
#%%
# 처음 URL에서 ? << 물음표 뒷 부분은 모두 제거하고 남은 url
url = "https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?"
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
"Connection": "keep-alive",
"Cookie": "ccsession=2023100518303100000ad00ad07afe; ccguid=2023100518303100000ad00ad07afe; ipmsperf_uuid=-480776048976768909; _KONEPS_PAGE=%3C%21%23%25%3EtbidListUrl%3C%40%25%7E%3E%2Fep%2Ftbid%2FtbidList.do%3Farea%3D%26areaNm%3D%26bidNm%3D%26bidSearchType%3D1%26budgetCompare%3D%26detailPrdnm%3D%26detailPrdnmNo%3D%26downBudget%3D%26fromBidDt%3D2023%252F04%252F04%26fromOpenBidDt%3D%26industry%3D%26industryCd%3D%26instNm%3D%26instSearchRangeType%3D%26intbidYn%3D%26orgArea%3D%26procmntReqNo%3D%26radOrgan%3D1%26recordCountPerPage%3D100%26refNo%3D%26regYn%3DY%26searchDtType%3D1%26searchType%3D1%26setMonth1%3D3%26strArea%3D%26taskClCds%3D5%26toBidDt%3D2023%252F10%252F05%26toOpenBidDt%3D%26upBudget%3D; JSESSIONID=MGpvlpGJdvZpbvgg1ZKrFJJcXpdpckfGqypy6hqJK1zv6tNqQFMx!71603225",
"Host": "www.g2b.go.kr:8101",
"Referer": "https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?searchType=1&bidSearchType=1&taskClCds=5&bidNm=&searchDtType=1&fromBidDt=2023%2F04%2F04&toBidDt=2023%2F10%2F05&setMonth1=3&fromOpenBidDt=&toOpenBidDt=&radOrgan=1&instNm=&instSearchRangeType=&refNo=&area=&areaNm=&strArea=&orgArea=&industry=&industryCd=&upBudget=&downBudget=&budgetCompare=&detailPrdnmNo=&detailPrdnm=&procmntReqNo=&intbidYn=®Yn=Y&recordCountPerPage=100",
"Sec-Ch-Ua": "\"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Windows\"",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
}
#
payload = {
"area": "",
"areaNm": "",
"bidNm": "",
"bidSearchType": "1",
"budgetCompare": "",
"detailPrdnm": "",
"detailPrdnmNo": "",
"downBudget": "",
"fromBidDt": "2023/04/04",
"fromOpenBidDt": "",
"industry": "",
"industryCd": "",
"instNm": "",
"instSearchRangeType": "",
"intbidYn": "",
"orgArea": "",
"procmntReqNo": "",
"radOrgan": "1",
"recordCountPerPage": "100",
"refNo": "",
"regYn": "Y",
"searchDtType": "1",
"searchType": "1",
"setMonth1": "3",
"strArea": "",
"taskClCds": "5",
"toBidDt": "2023/10/05",
"toOpenBidDt": "",
"upBudget": "",
"currentPageNo": "1",
"maxPageViewNoByWshan": "2"
}
res = requests.get(url, params = payload)
res.text
사실 headers가 없어도 잘 작동됩니다!!!
간혹 여러 이유로 headers가 꼭 필요할 때가 있는데, 그 부분은 나중에 다루도록 하고이번에는 headers를 지우고 이용하도록 하겠습니다
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 29 21:12:23 2023
@author: 진연녹
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
#%%
# 처음 URL에서 ? << 물음표 뒷 부분은 모두 제거하고 남은 url
url = "https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?"
#
payload = {
"area": "",
"areaNm": "",
"bidNm": "",
"bidSearchType": "1",
"budgetCompare": "",
"detailPrdnm": "",
"detailPrdnmNo": "",
"downBudget": "",
"fromBidDt": "2023/04/04",
"fromOpenBidDt": "",
"industry": "",
"industryCd": "",
"instNm": "",
"instSearchRangeType": "",
"intbidYn": "",
"orgArea": "",
"procmntReqNo": "",
"radOrgan": "1",
"recordCountPerPage": "100",
"refNo": "",
"regYn": "Y",
"searchDtType": "1",
"searchType": "1",
"setMonth1": "3",
"strArea": "",
"taskClCds": "5",
"toBidDt": "2023/10/05",
"toOpenBidDt": "",
"upBudget": "",
"currentPageNo": "1",
"maxPageViewNoByWshan": "2"
}
res = requests.get(url, params = payload)
res.text
지금 코드에서도, payload 내용 중 값이 비어있는 애들이 불필요해 보이시죠?불필요해 보이는 친구들 다 보내버리고 다시 작성해 볼게요~
우왕~ 다 지우고 나니 훨씬 짧아졌어요!!
코드에 필요해 보이는 주석들은 입력했더니 우리가 수정해야 할 부분이 확실하게 보이네요?
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 29 21:12:23 2023
@author: 진연녹
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
#%%
# 처음 URL에서 ? << 물음표 뒷 부분은 모두 제거하고 남은 url
url = "https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?"
#
payload = {
"bidSearchType": "1",
"fromBidDt": "2023/04/04",
"radOrgan": "1",
"recordCountPerPage": "100", # 한 페이지에 몇개 노출인가
"regYn": "Y",
"searchDtType": "1",
"searchType": "1", # 몰라도 되는 듯
"setMonth1": "3", # 최근1달 : 1, 최근2달:2, 최근6달:3
"taskClCds": "5", # 물품:1, 공사:3, 용역:5, 리스:6, 외자:2, 비축:11, 기타:4, 민간:20
"toBidDt": "2023/10/05",
"currentPageNo": "1", # 현재 페이지 번호
"maxPageViewNoByWshan": "2"
}
res = requests.get(url, params = payload)
res.text
일단 이전 포스팅 내용을 참고해서 테이블화 해보았어요
잘 불러와지는군요 ^^
이렇게 잘 될 때에는 자기 자신과 컴퓨터를 쓰담쓰담해주면서
세 번 칭찬해 주세요...
반드시 그래야 해요
5. 반복해서 수집 후 필터링 하기
# 나중에 쓸 변수 미리 생성
입찰공고목록_합 = pd.DataFrame()
# 더보기 10회 진행하기
i = 1
반복횟수 = 10
while i <= 반복횟수:
payload['currentPageNo'] = i
res = requests.get(url, params = payload)
if res.status_code == 200:
print(payload['currentPageNo'], '불러옴')
html = res.text
soup = BeautifulSoup(html, 'html.parser')
입찰공고목록_요소 = soup.find('table')
입찰공고목록_table = pd.read_html(str(입찰공고목록_요소))[0]
입찰공고목록_합 = pd.concat([입찰공고목록_합,입찰공고목록_table])
else:
print(i,' 번째 페이지 에러 확인해주세요')
i = i+1
# 필터링 하기 (공고명에 "건설관리", "실시설계", "기술진단" 이 포함된 내용만 추출)
keywords = ["건설관리", "실시설계", "기술진단"]
입찰공고목록_최종 = 입찰공고목록_합[입찰공고목록_합['공고명'].str.contains('|'.join(keywords))]
위 코드를 이용해서, 반복 + 데이터 수집 + 필터링까지 완료하면
총 1000 공고 중 96개가 남은 모습을 확인할 수 있네요~
가끔 보고 지나가는 님들아!!!!
아무 댓글 좀 달아줘요...
힘난단 말이에요
#전체 코드
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 29 21:12:23 2023
@author: 진연녹
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
#%%
# 처음 URL에서 ? << 물음표 뒷 부분은 모두 제거하고 남은 url
url = "https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?"
payload = {
"bidSearchType": "1",
"fromBidDt": "2023/04/04",
"radOrgan": "1",
"recordCountPerPage": "100", # 한 페이지에 몇개 노출인가
"regYn": "Y",
"searchDtType": "1",
"searchType": "1", # 몰라도 되는 듯
"setMonth1": "3", # 최근1달 : 1, 최근2달:2, 최근6달:3
"taskClCds": "5", # 물품:1, 공사:3, 용역:5, 리스:6, 외자:2, 비축:11, 기타:4, 민간:20
"toBidDt": "2023/10/05",
"currentPageNo": "1", # 현재 페이지 번호
"maxPageViewNoByWshan": "2"
}
res = requests.get(url, params = payload)
html = res.text
soup = BeautifulSoup(html, 'html.parser')
입찰공고목록_요소 = soup.find('table')
입찰공고목록_table = pd.read_html(str(입찰공고목록_요소))[0]
#%%
# 나중에 쓸 변수 미리 생성
입찰공고목록_합 = pd.DataFrame()
# 더보기 10회 진행하기
i = 1
반복횟수 = 10
while i <= 반복횟수:
payload['currentPageNo'] = i
res = requests.get(url, params = payload)
if res.status_code == 200:
print(payload['currentPageNo'], '불러옴')
html = res.text
soup = BeautifulSoup(html, 'html.parser')
입찰공고목록_요소 = soup.find('table')
입찰공고목록_table = pd.read_html(str(입찰공고목록_요소))[0]
입찰공고목록_합 = pd.concat([입찰공고목록_합,입찰공고목록_table])
else:
print(i,' 번째 페이지 에러 확인해주세요')
i = i+1
# 필터링 하기 (공고명에 "건설관리", "실시설계", "기술진단" 이 포함된 내용만 추출)
keywords = ["건설관리", "실시설계", "기술진단"]
입찰공고목록_최종 = 입찰공고목록_합[입찰공고목록_합['공고명'].str.contains('|'.join(keywords))]
'Python(파이썬) > 1. selenium' 카테고리의 다른 글
셀레니움(selenium) 나라장터 데이터 수집하기 4/4 (입찰방법/배정예산/추정가격 등 '용역 입찰공고 상세' 추가하기) (15) | 2023.10.10 |
---|---|
셀레니움(selenium) 나라장터 데이터 수집하기 2/4 (DataFrame 다루기 및 HTML 파싱) (0) | 2023.09.30 |
셀레니움(selenium) 나라장터 데이터 수집하기 1/4 (HTML frame 이동) (6) | 2023.09.29 |
셀레니움(selenium) 시작하기 (1) | 2023.09.29 |