-
반응형
내장 함수:
- len(iterable):
- 리스트, 튜플, 문자열 등의 길이를 반환합니다.
- type(object):
- 객체의 타입을 반환합니다.
- *print(objects, sep=' ', end='\n', file=sys.stdout, flush=False):
- 표준 출력에 값을 출력합니다.
- input(prompt):
- 사용자로부터 입력을 받습니다.
- int(x):
- 정수로 변환합니다.
- float(x):
- 부동 소수점 수로 변환합니다.
- str(x):
- 문자열로 변환합니다.
- list(iterable):
- 리스트로 변환합니다.
- tuple(iterable):
- 튜플로 변환합니다.
- **dict(kwargs):
- 딕셔너리로 변환합니다.
숫자 관련 함수:
- abs(x):
- 절대값을 반환합니다.
- max(iterable):
- 최댓값을 반환합니다.
- min(iterable):
- 최솟값을 반환합니다.
- sum(iterable):
- 모든 요소의 합을 반환합니다.
문자열 관련 함수:
- len(string):
- 문자열의 길이를 반환합니다.
- str.upper():
- 문자열을 대문자로 변환합니다.
- str.lower():
- 문자열을 소문자로 변환합니다.
- str.replace(old, new):
- 문자열에서 특정 문자열을 다른 문자열로 대체합니다.
- str.split(separator):
- 문자열을 구분자를 기준으로 나눕니다.
리스트 및 튜플 관련 함수:
- len(sequence):
- 리스트, 튜플 등의 길이를 반환합니다.
- sorted(iterable):
- 정렬된 리스트를 반환합니다.
- sum(iterable):
- 모든 요소의 합을 반환합니다.
- max(iterable):
- 최댓값을 반환합니다.
- min(iterable):
- 최솟값을 반환합니다.
기타:
- range(start, stop, step):
- 일정한 범위의 숫자를 생성합니다.
- help(object):
- 객체에 대한 도움말을 표시합니다.
- dir(object):
- 객체의 속성과 메서드 목록을 반환합니다.
- type(object):
- 객체의 타입을 반환합니다.
@@@ 주피터 노트북 단축키
a : 위에 새로운 셀 추가
b : 아래에 새로운 셀 추가
c : 셀 복사하기
v : 셀 붙여넣기
x : 셀 잘라내기
dd : 셀 삭제하기
p : 셀 아래에 붙여넣기
o : 실행결과 열기/닫기
m : Markdown으로 변경
y : Code로 변경
Shift + m : 선택 셀과 아래 셀과 합치기
Shitf + Ctrl + - : 커서 위치에서 셀 둘로 나누기
Ctrl + s 또는 s : 파일 저장
Enter : 선택 셀의 코드 입력 모드로 돌아가기
Ctrl + / : 커서 위치 라인 주석처리
요즘 셀레니움(selenium)을 이용해서 크롤링을 하고 있습니다. 지금까지의 느낌으로는 예전에 사용해본 beautifulsoup보다 훨씬 사용하기 쉬운 것 같습니다.
어떤 링크나 버튼을 클릭할 때 click() 함수를 사용하곤 합니다.
driver.find_element_by_css_selector("css 셀렉터").click()
그런데 어떤 이유인지는 정확히 몰라도 click() 함수가 안 먹힐 때가 있더라고요. 이때는 send_keys(Keys.ENTER) 함수를 사용하면 대부분 문제가 해결됩니다.
driver.find_element_by_css_selector("css 셀렉터").send_keys(Keys.ENTER)
물론 css 셀렉터 부분에는 여러분이 크롤링하고자 하는 요소의 선택자(셀렉터, selector)를 넣어주셔야 합니다.
@@@ 배열 열 타이틀 생성 및 기본 값
test_taste_df['카카오별점'] = 0
배열 카카오별점 행의 열을 num 순서대로 입력
test_taste_df['카카오별점'].iloc[num] = '입력값'
star = test_taste_df['카카오별점'].iloc[num] //입력된 값 호출
@@@ 배열 행추가
df.loc[0] = arr_list or [1, 2, 3] 맞춰서
@@@ 배열 열추가 - 합치기
arr_df = pd.concat([arr_df,title_arr])
@@@ 특정 열만 출력 '순번', '상호','지역','1등 자동 당첨 건수','위도','경도' 순번 제외하고
shop_df = shop_df[['상호','지역','1등 자동 당첨 건수','위도','경도']]
@@@ Find_element 속성
from seleniuhttp://m.webdriver.common.by import By
driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_element(By.XPATH, '//button')
driver.find_element(By.ID, 'loginForm')
driver.find_element(By.LINK_TEXT, 'Continue')
driver.find_element(By.PARTIAL_LINK_TEXT, 'Conti')
driver.find_element(By.NAME, 'username')
driver.find_element(By.TAG_NAME, 'h1')
driver.find_element(By.CLASS_NAME, 'content')
driver.find_element(By.CSS_SELECTOR, 'p.content')
driver.find_elements(By.ID, 'loginForm')
driver.find_elements(By.CLASS_NAME, 'content')
By 속성은 아래와 같습니다.
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
@@@ 링크주소 가져오기
driver.find_element(By.XPATH, '//*[@id="contentarea"]/div[3]/table[2]/tbody/tr/td[12]/a').get_attribute("href")
# 링크주소 가져오기 추가로 링크 파라미터값에서 page 값 추출
pattern_id = re.compile("page=..", re.IGNORECASE)
url = driver.find_element(By.CSS_SELECTOR, '#contentarea > div.box_type_l > table.Nnavi > tbody > tr > td.pgRR > a').get_attribute("href")
pattern_id.search(url).group()
@@@ 함수 상단에 넣으면 동일 자료를 가져올때 캐시에서 가져와서 속도 증가.... 중복 데이타 확인 필요
from functools import cache
@cache
def ......
@@@ 함수 실행 속도
start = time.time() # 시작
add_data() ## 확인하고 자하는 함수
print(f"{time.time()-start:.4f} sec") # 종료와 함께 수행시간 출력
@@@ 일정 시간 후 실행
#셀레니움 진행중 대기 관련 라이브러리
from seleniuhttp://m.webdriver.common.by import By
from seleniuhttp://m.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver,5).until(EC.presence_of_element_located(
(By.XPATH, '//*[@id="_pcmap_list_scroll_container"]/ul/li[1]/div[1]/a[1]'))).text
@@@ iframe 형식인 경우는 프레임 이동 선언 후 처리 (실행은 한번만 해야 함
searchIframe = driver.find_element(By.ID,'searchIframe')
driver.switch_to.frame(searchIframe)
@@@ iframe 초기화 후 재설정
driver.switch_to.default_content() # Iframe 초기화
entryIframe = driver.find_element(By.ID, 'entryIframe')
driver.switch_to.frame(entryIframe)
@@@ class="PXMot LXIwF" 클래스가 2가 이상인 경우는 "." 을 추가
driver.find_element(By.CLASS_NAME, 'PXMot.LXIwF').text
@@@ 정규표현식 문자바꾸기
test_start = '별점\n4.5/5'
test_start = re.sub('별점\n|/5','',test_start)
@@@ 대기 sleep 이외 암시적 대기와 명시적 대기 방법
Explicity Wait(명시적대기) : 설정한 시간까지 최대한 대기 후 , 지정한 조건의 요소가 보이면 코드를 진행한다.
WebDriverWait(driver, 지정하는 최대시간).until(EC.presence_of_element_located((By.ID,"ID 이름)))
: driver 실행중 until 조건을 실행할때까지 최대한 지정한 시간까지 대기한다.
EC.element_to_be_clickable 는 해당 element를 클릭 할수 있을때의 조건
By 뒤에는 ID, CLASS_NAME, XPath 등 다양한 요소를 입력할수 있다.
# 왼쪽 프레임 설정 SearchIframe ID 찾는 동안 최대 3초 대기
WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.ID, "searchIframe")))
searchIframe = driver.find_element(By.ID,'searchIframe')
driver.switch_to.frame(searchIframe)
# 각 카드 상단 클릭 card 상단 xpath가 보일때까지 최대 3초
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.ID, "'//*[@id="_pcmap_list_scroll_container"]/ul/li['+format(num)+']/div[1]/a[1]/div/div/span[1]'")))
driver.find_element(By.XPATH, '//*[@id="_pcmap_list_scroll_container"]/ul/li['+format(num)+']/div[1]/a[1]/div/div/span[1]').click()
@@@ DataFram 중복값 제거
naver_df.drop_duplicates() // 이게 안되서
naver_df = naver_df.drop_duplicates() //이렇게 하면 되네
# MF 칼럼만 지정하여 중복되는 행 제거
df.drop_duplicates(['MF'])
# MF, Age 2개의 칼럼을 지정하여 중복되는 행 제거
df.drop_duplicates(['MF', 'Age'])
# 중복 데이터 전부 제거 :: False
df.drop_duplicates(['MF', 'Age'], keep = False)
# 맨 위 / 첫 번째 행 남기고 전부 제거 :: first
df.drop_duplicates(['MF', 'Age'], keep = 'first')
# 맨 아래 / 마지막 행 남기고 전부 제거 :: last
df.drop_duplicates(['MF', 'Age'], keep = 'last')
# keep 에 아무것도 지정하지 않으면 디폴트 값은 'first'
# MF 열을 기준으로 중복 여부만 확인하기
dup = df.duplicated(['MF'])
# 여기서 dup의 데이터타입은 Series
dup
# 원래 데이터프레임에 중복여부 칼럼 추가 => 새로운 데이터프레임 생성
df_dup = pd.concat([df, dup], axis=1)
# 새로운 데이터프레임의 열 이름 바꾸기
df_dup.rename(columns = {0 : 'Dup'}, inplace = True)
@@@ input 인터키
driver.find_element(By.ID, 'search.keyword.query').send_keys(Keys.RETURN)
driver.find_element(By.ID, 'search.keyword.query').clear() //input 값 초기화
driver.find_element(By.ID, 'search.keyword.query').send_keys('입력값')
@@@ 폴리움 folium 엑셀 읽어오기
read_csv , read_xlsx('경로', encoding='인코딩형식')
shop_df = pd.read_csv('lotto.csv', encoding='cp949')
@@@ 지도검색 다음지도 api 생성한 REST API 키 {57243a05e73d142330ad82f6983ad44a}
kakao_url = 'https://dapi.kakao.com/v2/local/search/keyword.json?query=대구 달서구 이등복권판매점'
api_key = {'Authorization':'KakaoAK 57243a05e73d142330ad82f6983ad44a'}
shop_place = requests.get(kakao_url, headers=api_key).json()
// 이렇게 불러올수 있음
shop_place = requests.get(kakao_url, headers=api_key).json()['documents'][0]
{'documents': [{'address_name': '대구 달서구 본리동 2-16',
'category_group_code': '',
'category_group_name': '',
'category_name': '가정,생활 > 취미 > 복권',
'distance': '',
'id': '15726733',
'phone': '053-522-6808',
'place_name': '일등복권편의점',
'place_url': 'http://place.map.kakao.com/15726733',
'road_address_name': '대구 달서구 대명천로 220',
'x': '128.53614960474',
'y': '35.8421935317643'},
{'address_name': '대구 달서구 월암동 1-224',
'category_group_code': '',
'category_group_name': '',
0 번째 값만 호출
shop_place['documents'][0]
0 번째값에서 x 값호출
shop_place['documents'][0]['x'] ===> '128.53614960474'
0 번째값에서 y 값호출
shop_place['documents'][0]['x'] ===> '35.8421935317643'
searching = shop_df['지역'][cnt]+ " " + shop_df['상호'][cnt]
url = 'https://dapi.kakao.com/v2/local/search/keyword.json?query={}'.format(searching)
@@@ 지도에 아이콘 넣기
카이스트에 지도표기
korea_center = folium.Map(location = [36.3505, 127.3848], zoom_start=8)
folium.Marker(
location = [36.3505, 127.3848],
popup = 'KAIST',
icon = folium.Icon(color='blue',icon='start')
).add_to(korea_center)
korea_center 값에 빨간 원으로 포항공대 추가
folium.CircleMarker(
[36.0139, 129.3232],
radius = 10,
color = '#ff0000',
fill_color='#ff0000',
popup = 'POSTECH').add_to(korea_center)
빨간 원으로 당첨 상호 표시(여러번 된곳은 원이크게)
shop_df
상호 지역 1등 자동 당첨 건수 위도 경도
0 일등복권편의점 대구 달서구 5 0 0
1 오케이상사 서울 서초구 3 0 0
2 세진전자통신 대구 서구 2 0 0
# 줌 8배울 대전시청 기준 우리나라 지도 불러오기
final_map_korea = folium.Map(location = [36.3505, 127.3848], zoom_start=8)
for cnt in range(0, len(shop_df)):
try:
folium.CircleMarker([address_finder(cnt)['위도'][0], address_finder(cnt)['경도'][0]],
radius = int(address_finder(cnt)['1등 자동 당첨 건수'][0])*4,
popup = address_finder(cnt)['상호'][0],
color = '#FF0000',
fill_color = '#FF0000'
).add_to(final_map_korea)
except:
pass
생성 지도 내보내기
final_map_korea.save('Lotto_map.html')
@@@
삼성전자 재무제표 가져오기 (F12에서 네트워크 하단에서 값추출 책 242 확인)
test_url = 'https://navercomp.wisereport.co.kr/v2/company/ajax/cF1001.aspx?'
test_params = {
'cmp_cd' : '005930',
'fin_typ' : '4',
'freq_typ' : 'Y',
'encparam' : 'Zk80d3Y1dVNyVzl2ZmU0eXZIZVNkdz09'
}
test_headers = {
'Accept' : 'text/hmlt, */*; q=0.01',
'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',
'Host' : 'navercomp.wisereport.co.kr',
'Referer' : 'https://navercomp.wisereport.co.kr/v2/company/c1010001',
'X-Requested-With' : 'XMLHttpRequest'
}
생성된 파일 padas에 배열처리
pd.read_html(test_response.text)
requests.get(base_url).text.find('encparam')
>>> 52798 줄에 있음
requests.get(base_url).text[53400:53600]
>>> 53400~53600 줄 사이 호출
@@@ 페이지에서 테이블 가져오기
test_df = pd.read_html('https://finance.naver.com/sise/sise_market_sum.naver', header=0, encoding='cp949')[1]
test_df
test_df.to_excel('엑셀.xlsx') ''' 엑셀저장시 타이틀을 맞춰야 함 '''
test_fd = pd.read_html('https://finance.naver.com/sise/sise_market_sum.naver', header=0, encoding='cp949')
테이블이 여러게 인경우는
test_fd[0] 첫번째테이블 출력
test_fd[1] 두번째테이블 출력
@@@ NaN 값
# 셀의 값이 None인 것만 출력
df[df['컬럼명'].isnull()]
# 셀의 값이 None이 아닌 것만 출력
df[df['컬럼명'].notnull()]
@@@ 패턴처리
#패턴 정의 > \n과 같은 줄바꿈 텍스트를 제외하고 대소문자 구분없이 (re.IGNORECASE를 의미), encparm:뒤의 따옴표
#안의 값(' ') 1개 이상을 가져올것'
pattern = re.compile("encparam: '(.+)'", re.IGNORECASE)
#정규표현식 패터.search(본문) > 본문 내에서 지정한 정규표현식 패터을 활용하여 찾음
pattern.search(requests.get(base_url).text)
>>> <re.Match object; span=(52798, 52842), match="encparam: 'dXdtUUVtMGl1cGRxWm1TTnpqRktrUT09'">
# 객체,groups() 각 그룹에 해당하는 문자열을 튜플 형태로 내보냄
pattern.search(requests.get(base_url).text).groups()
('dXdtUUVtMGl1cGRxWm1TTnpqRktrUT09',)
@@@@ 행열 변경 DataFrame.transpose()
함수에서 추출한 컬럼과 인덱스를 서루 바꿈
financial_statement('005930').transpose()
@@@@ 인덱스 재정렬 DataFrame.reset_index()
financial_statement('005930').transpose().reset_index()
@@@ 0번째 컬럼을 컬럼명으로 지정
test_df = financial_statement('005930').transpose().reset_index()
test_df.columns = test_df.loc[0]
@@@ drop으로 원하는 칼럼 또는 인덱스 제거. 중복되는 index 0값 젲거
DataFrame.drop(칼럼명 또는 인덱스값, axis=0(인덱스) 또는 1(칼럼), inplace=True(고정)/False(고정하지않음)
test_df.drop([0],axis=0,inplace=True)
@@@ CSV 파일 읽어오기
with open('krx_data.csv', encoding='cp949') as f:
company = f.read()
특정 문자 기준으로 리스트화
with open('krx_data.csv', encoding='cp949') as f:
company = f.read().split('\n')
company[0] 0번째 행 출력
company[1] 1번째 행 출력
>> company[0]
'표준코드,단축코드,한글 종목명,한글 종목약명,영문 종목명,상장일,시장구분,증권구분,소속부,주식종류,액면가,상장주식수'
>> company[0].split(",")
['표준코드',
'단축코드',
'한글 종목명',
'한글 종목약명',
'영문 종목명',
'상장일',
'시장구분',
'증권구분',
'소속부',
'주식종류',
'액면가',
'상장주식수']
>> company[0].split(",")[0]
'표준코드'
>> company[1]
'KR7098120009,98120,(주)마이크로컨텍솔루션,마이크로컨텍솔,"Micro Contact Solution Co.,Ltd.",2008-09-23,KOSDAQ,주권,중견기업부,보통주,500,8312766'
@@@ 쌍따옴표 변환
>> company[1].split(",")[3].replace('"', '')
'KR7095570008,95570,AJ네트웍스보통주,AJ네트웍스,"AJ Networks Co.,Ltd.",2015-08-21,KOSPI,주권,,보통주,1000,46822295'
@@@ 리스트 안의 인덱스를 반복함
index_num in enumerate(company)
for count, index_num in enumerate(company[1:]): 리스트 1번행부터 마지막까지
>> for count, index_num in enumerate(company):
print(count,
index_num.split(",")[1].replace('"', ''),
index_num.split(",")[3].replace('"', '')
)
>> 20의 배수마다 진행 상황 카운트 출력 및 랜덤하게 2~3초 쉬기
if count % 20 == 0:
print(count)
time.sleep(random.uniform(2,4))
@@@ try except
print("== Program Start")
try:
arr = ['b', 'l', 'o', 'g']
print(arr[0])
print("== Mid")
except:
print("== error!! but, still alive")
else:
print("== else")
print("== Program End")
@@@ final_df.columns 컬럼명 가져오기
Index(['주요재무정보', '주요재무정보', '주요재무정보', '주요재무정보', '매출액', '영업이익',
'영업이익(발표기준)', '세전계속사업이익', '당기순이익', '당기순이익(지배)', '당기순이익(비지배)', '자산총계',
'부채총계', '자본총계', '자본총계(지배)', '자본총계(비지배)', '자본금', '영업활동현금흐름', '투자활동현금흐름',
'재무활동현금흐름', 'CAPEX', 'FCF', '이자발생부채', '영업이익률', '순이익률', 'ROE(%)',
'ROA(%)', '부채비율', '자본유보율', 'EPS(원)', 'PER(배)', 'BPS(원)', 'PBR(배)',
'현금DPS(원)', '현금배당수익률', '현금배당성향(%)', '발행주식수(보통주)', '종목코드', '종목명', '섹터'],
dtype='object', name=0)
@@@ 컬럼명 재정렬
final_df = final_df[['종목코드', '종목명', '주요재무정보', '주요재무정보', '매출액', '영업이익', '영업이익(발표기준)', '세전계속사업이익', '당기순이익',
'당기순이익(지배)', '당기순이익(비지배)', '자산총계', '부채총계', '자본총계', '자본총계(지배)',
'자본총계(비지배)', '자본금', '영업활동현금흐름', '투자활동현금흐름', '재무활동현금흐름', 'CAPEX', 'FCF',
'이자발생부채', '영업이익률', '순이익률', 'ROE(%)', 'ROA(%)', '부채비율', '자본유보율',
'EPS(원)', 'PER(배)', 'BPS(원)', 'PBR(배)', '현금DPS(원)', '현금배당수익률',
'현금배당성향(%)', '발행주식수(보통주)', '섹터']]
@@@ 엑셀로 내보내기
final_df.to_excel('엑셀.xlsx')
@@@ 값에서 숫자만 추출
import re
string = 'aaa1234, ^&*2233pp'
numbers = re.sub(r'[^0-9]', '', string)
print(numbers)
@@@
아나콘다 3 32비트
//32비트 변경
set CONDA_FORCE_32BIT=1
// 가상 재생성
conda create -n quant python=3.8
기타 필요한것은 conda env list
conda activate quant
pip install pyqt5
//64비트
set CONDA_FORCE_32BIT=
@@@@
return df ==> 첫행 내림차순
return df[::-1] ==> 첫행 오름차순
@@@@
Tor browser 로 selenium webdriver 크롤링 ip 우회
from selenium
import webdriver from seleniuhttp://m.webdriver.chrome.options
import Options
for i in range(3):
chrome_options = Options()
chrome_options.add_argument("--proxy-server=socks5://127.0.0.1:9150")
driver = webdriver.Chrome(executable_path='C:/Users/user/Desktop/크롤링/crawler/crwaling code/chromedriver/chromedriver.exe', options=chrome_options)
driver.get('https://whatismyipaddress.com/')
# 검색어 입력
search = input("검색할 키워드를 입력해주세요:")
# 검색 시작할 페이지 입력
page = int(input("\n크롤링할 시작 페이지를 입력해주세요. ex)1(숫자만입력):")) # ex)1 =1페이지,2=2페이지...
print("\n크롤링할 시작 페이지: ", page, "페이지")
# 검색 종료할 페이지 입력
page2 = int(input("\n크롤링할 종료 페이지를 입력해주세요. ex)1(숫자만입력):")) # ex)1 =1페이지,2=2페이지...
print("\n크롤링할 종료 페이지: ", page2, "페이지")
# naver url 생성
search_urls = makeUrl(search, page, page2)
파이썬 종료 중지 명령어
close()
현재 활성화 되어있는 webdriver 하나의 tab만 종료
quit()
모든 Tab 종료. 2개 이상의 webdriver가 열려있다면 quit()를 써야한다.
exit()
site-package라는 패키지 안에서 가져온 함수로 site-package 참조문제가 일어날수 있다.
주로 대화형 셀에서 사용된다
sys.exit()
일반적인 프로그램 (vscode)에서 사용되며, sys 모듈을 import해서 사용한다.반응형 - len(iterable):