일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 파이썬
- to shp
- 2164 카드2
- Chat-GPT
- kmeans
- colab runtime
- plotly dash
- 혁신성장부문
- geoDataFrame
- 백준
- 인스타그램
- Merge Repositories
- python buildpacks
- string to list
- clustering
- 웹페이지
- convert to shp
- 알고리즘
- Crawling
- 플라스크
- NLP
- geopandas
- 코랩 런타임
- Selenium
- 셀레니움
- 크롤링
- 괄호 문제
- Python
- 해시태그
- flask
Archives
- Today
- Total
코딩코딩코딩
인스타그램 해시태그 크롤링 및 분석 - 3 본문
앞에서 했던 작업들을 모두 함수로 만들어서 작업했습니다.
# Create Empty List & Parameter Setting
url = 'http://www.instagram.com'
path = 'C:\\Users\\rectworks\\Downloads\\chromedriver_win32\\chromedriver.exe'
SCROLL_PAUSE_TIME = 3.0
ID = 'user_id'
PW = 'password'
post_link = []
popularPost_len = []
id_list = []
like_list = []
tag_list = []
link_list = []
date_list = []
month_list = []
day_list = []
def instagram_login(id, pw):
driver.get(url)
driver.implicitly_wait(5)
driver.find_element_by_name('username').send_keys(id) # id 입력
elem_pw = driver.find_element_by_name('password') # pw 입력
elem_pw.send_keys(pw)
elem_pw.submit()
driver.implicitly_wait(5) # 파싱될 때까지 5초 기다림 (미리 완료되면 waiting 종료됨)
driver.find_element_by_class_name('cmbtv').click() # 비밀번호 저장하지 않음
driver.implicitly_wait(5)
driver.find_element_by_xpath('/html/body/div[4]/div/div/div/div[3]/button[2]').click() # 알림설정 무시
def main_search(keyword):
search = driver.find_element_by_xpath('//*[@id="react-root"]/section/nav/div[2]/div/div/div[2]/input')
search.clear()
search.send_keys(keyword)
search_list1 = driver.find_element_by_xpath('//*[@id="react-root"]/section/nav/div[2]/div/div/div[2]/div[3]/div[2]/div/a[1]')
search_list1.click()
def scroll_page():
post_link.clear()
popularPost_len.clear()
while True:
pageString = driver.page_source # page_source : 현재 렌더링된 페이지의 Elements를 모두 가져옴
bsObj = bs(pageString, 'lxml')
for postline in bsObj.find_all(name='div', attrs={"class":"Nnq7C weEfm"}):
a_len = len(postline.select('a'))
popularPost_len.append(a_len)
# 인스타그램 게시물은 행별로 최대 3개까지 확인할 수 있는데, 최근게시물이나 마지막 게시물은 1,2개가 나올 수도 있어서 len 지정
for post in range(a_len):
item = postline.select('a')[post]
link = item.attrs['href']
if link not in post_link: # 스크롤을 내리고 중복된 것을 제거하지 않고 누적시키기 때문에 없는 것만 추가
post_link.append(link)
last_height = driver.execute_script('return document.body.scrollHeight') # 자바스크림트로 스크롤 길이를 넘겨줌
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # selenium에서 scroll 기능 사용
time.sleep(SCROLL_PAUSE_TIME)
# 프로세스 자체를 지정시간동안 기다려줌(무조건 지연)
#driver.implicitly_wait(SCROLL_PAUSE_TIME)
# 브라우저 엔진에서 파싱되는 시간을 기다려줌(요소가 존재하면 지연없이 코드 실행)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(SCROLL_PAUSE_TIME)
#driver.implicitly_wait(SCROLL_PAUSE_TIME)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
else:
last_height = new_height
continue
def popularPostSum():
popularPost = 0
for i in range(3):
popularPost += popularPost_len[i]
return popularPost
# 인기게시물은 시간순으로 나타나는 것이 아니므로
# 여기에 나타나는 항목들은 시간순으로 데이터프레임 만다는 데서 제외시키기 위한 함수
def date_based_crawling(std_date):
id_list.clear()
like_list.clear()
tag_list.clear()
link_list.clear()
date_list.clear()
month_list.clear()
day_list.clear()
post_linkx = post_link[popularPostSum():] # 스크롤 내리면서 모은 데이터 중 인기 게시물은 제외시킴
num_of_postx = len(post_linkx)
date_string = std_date
date =datetime.strptime(date_string, "%Y.%m.%d")
time_tuple = date.timetuple()
std_timestamp = int(time.mktime(time_tuple))
# 기준 날짜를 지나면 크롤링이 멈추도록 작동
for i in tqdm_notebook(range(num_of_postx)):
req = Request("https://www.instagram.com" + post_linkx[i], headers={'User-Agent': 'Mozila/5.0'})
postpage = urlopen(req).read()
req_next = Request("https://www.instagram.com" + post_linkx[i+1], headers={'User-Agent': 'Mozila/5.0'})
postpage_next = urlopen(req_next).read()
post_body = bs(postpage, 'lxml', from_encoding='utf-8')
post_core = post_body.find('meta', attrs={'property':"og:description"})
contents = post_core['content']
# break할 시간 비교
posttxt = str(postpage)
timestamp = int(posttxt[posttxt.find('taken_at_timestamp')+20 : posttxt.find('taken_at_timestamp')+30])
posttxt_next = str(postpage_next)
timestamp_next = int(posttxt_next[posttxt_next.find('taken_at_timestamp')+20 : posttxt_next.find('taken_at_timestamp')+30])
if (std_timestamp > timestamp) \
and (datetime.fromtimestamp(timestamp).strftime('%Y/%m/%d %H:%M'))\
== (datetime.fromtimestamp(timestamp_next).strftime('%Y/%m/%d %H:%M')):
break
# 시간
date_list.append(datetime.fromtimestamp(timestamp).strftime('%Y/%m/%d %H:%M'))
month_list.append(datetime.fromtimestamp(timestamp).strftime("%m"))
day_list.append(datetime.fromtimestamp(timestamp).strftime("%d"))
# 개별 링크 리스트
link_list.append("https://www.instagram.com" + post_linkx[i])
# 좋아요
try:
likes = int(contents[: contents.find(' Likes, ')]) # Likes 문자열 앞에 있는 좋아요 개수 추출
except:
likes=0 # 좋아요 가 아니라 조회수로 표시되는 경우도 있어 이런 경우는 0으로 표시
like_list.append(likes)
# 개별 계정
if "@" and ")" in contents:
personal_id = contents[contents.find("@")+1 : contents.find(")")]
elif "@" and ")" not in contents and "on Instagram" in contents:
personal_id = contents[contents.find("@")+1 : contents.find('on Instagram')]
else :
personal_id = contents[1: contents.find(' posted on')]
id_list.append(personal_id)
'''
(@personal_id) on instagram, @persoanlid posted on instagram, personal_id on instgram 등의 형태로 meta 데이터에 표시되기
때문에 여러 형식별 id 추출 if문 수행
'''
# 해시태그
tag_list.append([])
for tag_content in post_body.find_all('meta', attrs={'property':"instapp:hashtags"}):
hashtags = tag_content['content'].rstrip(',')
tag_list[i].append(hashtags)
코드 중간에 if, break문을 써놓은 부분은 게시물을 크롤링해오던 중 중간에 갑자기 한 달 전 게시물이 뜬금없이 들어가있어서 뒤 게시물과 날짜가 같으면 break하도록 작성했습니다. 대부분의 게시글은 분,시간 단위로 올라와서 날짜로 비교해도 상관없을 것 같습니다.
다만 이렇게 날짜를 비교하는 코드를 넣으니 속도가 너무 느려져셔 개선해야 할 것 같습니다.
'파이썬 > 텍스트마이닝' 카테고리의 다른 글
인스타그램 해시태그 크롤링 및 분석 - 5 (5) | 2020.07.29 |
---|---|
인스타그램 해시태그 크롤링 및 분석 - 4 (5) | 2020.07.27 |
인스타그램 해시태그 크롤링 및 분석 - 2 (5) | 2020.07.23 |
인스타그램 해시태그 크롤링 및 분석 - 1 (1) | 2020.07.21 |
파이썬 네이버 뉴스 일일 기사 크롤링 - 3 (1) | 2020.07.20 |
Comments