Skip to content

Instantly share code, notes, and snippets.

@DanielTimLee
Last active March 28, 2017 19:09
Show Gist options
  • Save DanielTimLee/e01056cb27371516d8c5f1e0b0776dca to your computer and use it in GitHub Desktop.
Save DanielTimLee/e01056cb27371516d8c5f1e0b0776dca to your computer and use it in GitHub Desktop.
crawler_init.py
class Fb_config():
def __init__(self, target):
self.target = target
# TODO : 항상 타겟이 이렇게 세팅되지 않음. profile.php?id=<int> 이렇게 붙기도 함
# 이럴때는 sk=likes 이렇게 붙음.
# maps에서 이미 다 출력했는데 아무 메시지가 나오지 않을 때도 있음.
self.base_url = "https://www.facebook.com/" + target
# TODO: 너무 self 많이 썼는데 사용하지 않고 할 수 있는 방법 찾기
self.TIMELINE_CLASS = "_1w_m"
self.LIKE_CLASS = "ul.uiList._4-sn._5k35._620._509-._4ki"
self.MAP_CLASS = "ul.uiList._620._14b9._509-._4ki"
self.EVENT_CLASS = "ul.uiList._4-sn._509-._4ki"
self.GROUP_CLASS = "ul.uiList._4-sn._509-._4ki"
self.MOVIE_CLASS = "ul.uiList._620._14b9._5pst._5psx._509-._4ki"
self.BOOK_CLASS = "ul.uiList._620._14b9._5pst._5psx._509-._4ki"
# "<target> 추가 정보"
self.STOP_CLASS = ".mbm._5vf.sectionHeader._4khu"
self.NOT_FOUND_CLASS = "div._4-y-"
self.NOT_FOUND_TEXT = "없음"
self.LOGIN_FAILED_TEXT = "Facebook에 로그인"
# TODO: profile 아직 긁는 기능 없음
"""
정보
- 개요
- 경력 및 학력
- 거주했던 장소
- 연락처 및 기본 정보
- 가족 및 결혼 연애 상태
- <target>에 대한 자세한 소개
- 중요 이벤트
"""
self.url_list = {
# "timeline": ["타임라인", self.base_url,self.TIMELINE_CLASS],
# 사용자 정보 항목
# "profile": ["프로필", self.base_url + '/about'],
"likes": ["좋아요", self.base_url + '?sk=likes', self.LIKE_CLASS],
"map": ["체크인", self.base_url + '?sk=map', self.MAP_CLASS],
"events": ["이벤트", self.base_url + '?sk=events', self.EVENT_CLASS],
"groups": ["그룹", self.base_url + '?sk=groups', self.GROUP_CLASS],
# movie & book are watched event.
"movies": ["영화", self.base_url + '?sk=video_movies_watch', self.MOVIE_CLASS],
"books": ["책", self.base_url + '?sk=books_read', self.BOOK_CLASS]
}
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import crawler.config as global_config
class smtm_crawler():
def __init__(self, email, pwd, target):
self.email = email
self.pwd = pwd
self.target = target
self.options = Options()
self.options.add_argument("--disable-notifications")
# self.options.add_argument("--start-fullscreen")
self.config = global_config.Fb_config(self.target)
self.driver = None
def init(self):
self.driver = webdriver.Chrome(chrome_options=self.options)
self.driver.get("http://www.facebook.org")
assert "Facebook" in self.driver.title
self.__signin()
def __signin(self):
elem = self.driver.find_element_by_id("email")
elem.send_keys(self.email)
elem = self.driver.find_element_by_id("pass")
elem.send_keys(self.pwd)
elem.send_keys(Keys.RETURN)
if self.config.LOGIN_FAILED_TEXT in self.driver.title:
print("로그인에 실패하였습니다.<br/>")
quit()
print("로그인에 성공했습니다.<br/>")
def start(self):
data={}
for key, value in self.config.url_list.items():
access = yield from self.__access_target(key, value[0], value[1])
if access:
yield from self.__scroll_end()
yield("글을 긁는 중입니다.<br/>")
posts = self.driver.find_elements_by_css_selector(value[2])
text_data = ''
for post in posts:
text_data = text_data + post.text
data[key] = text_data
yield("페이스북 스크롤이 모두 완료되었습니다.<br/>")
self.driver.close()
# return data
def __access_target(self, key, scope, scope_url):
yield(self.target + " " + scope + " 에 접근 중입니다.<br/>")
self.driver.get(scope_url)
self.driver.implicitly_wait(3)
# TODO : 로깅 모듈 사용
if key in self.driver.current_url:
return True
elif self.driver.title == "페이지를 찾을 수 없음":
yield("Error : 페이지를 찾을 수 없음.<br/>")
return False
elif key not in self.driver.current_url:
yield("Warning : 회원이 해당 내용을 공개하지 않았습니다.<br/>")
return False
def __scroll_wait(self):
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
self.driver.implicitly_wait(1) # seconds
def __scroll_end(self):
# TODO : Try Catch 안하고 사용할 수 있는 셀레늄 함수 찾아보기
try:
if self.config.NOT_FOUND_TEXT in self.driver. \
find_element_by_css_selector(self.config.NOT_FOUND_CLASS).text:
yield("결과가 존재하지 않습니다.<br/>")
return False
except:
pass
while True:
yield("스크롤 하는 중입니다.<br/>")
try:
if self.driver.find_element_by_css_selector(self.config.STOP_CLASS).is_displayed():
break
except:
pass
self.__scroll_wait()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment