def get_daum_title(search_string=None): ''' 이 함수는 다음 포탈에서 문자열을 검색 후 검색결과 중 제목 List를 Return 합니다. Daum 검색결과는 class이 "inner_article"인 <div> 태그 하부에 존재 합니다. 검색결과는 블로그, 웹문서, 브런치, 이미지, 뉴스, 카페글 섹션으로 구분되어 있고, 다행이 각 섹션의 <div> 태그의 class명이 "g_comp"로 동일 합니다. 세부 검색 리스트는 "g_comp" class 하부에 포함된 <ul> 태그 아래 <li> 태그들 아래에 존재합니다. 찾고자 하는 제목은 <li> 태그 아래에 <a> 태그에 있지만, <a> 태그까지 찾아가는 경로는 섹션마다 조금씩 다르고, <li> 태그 내에는 불필요한 <a> 태그도 존재합니다. 블로그, 웹문서, 뉴스, 카페글 섹션은 제목을 나타내는 <a> 태그의 바로 위 <div> 태그의 class명이 "mg_tit"로 동일 합니다. "mg_tit" class명을 이용해서 블로그, 웹문서, 뉴스, 카페글에서 제목을 추출합니다. search_string: 검색할 문자열(String) ''' html = get_download(daum_url, params={"q": search_string}) dom = BeautifulSoup(html.text, "lxml") divTags = dom.find_all("", {"class": "mg_tit"}) result = [] for tag in divTags: a = tag.find("a") if a != None: result.append(a.text.strip()) return result
def __init__(self): self._url = "https://news.naver.com/" self._html = get_download(self._url) self._dom = BeautifulSoup(self._html.text, "html.parser") self._category_names = ['정치', '경제', '사회', '생활문화', '세계', 'IT과학'] self._category_codes = { self._category_names[0]: "00", self._category_names[1]: "01", self._category_names[2]: "02", self._category_names[3]: "03", self._category_names[4]: "04", self._category_names[5]: "05" } self._ranks = { '1': '01', '2': '02', '3': '03', '4': '04', '5': '05', '6': '06', '7': '07', '8': '08', '9': '09', '10': '10' } self._path = "" self._newslists = [] # 6개 카테고리, 10개 기사, 랭크/제목/링크 self._dirs = [] # 뉴스 기사가 저장된 폴더 리스트 self._filenames = [] # 저장된 파일 리스트(전체 폴더 또는 최근 폴더) self._articles = "" # 다운로드 한 기사 전체 내용(지정한 섹션 기사) self._all_articles = "" # 누적된 다운로드 기사 전체 내용(지정한 섹션 기사) self._article = "" # 다운로드 한 기사 1건
def get_site_urls(link, depth=3): ''' link 사이트를 다운로드 받은 후 html에 포함된 url를 추출하여, url과 depth를 dictionary list를 반환 합니다. internalLink와 externalLink로 구분 후 internalLink는 scheme과 netloc를 추가해 절대 주소로 바꾼 후 dictionary에 추가한다. link: 탐색할 url depth: 탐색할 url이 처음 시작한 url로 부터 몇번째 depth인지 나타내며, default는 3보다 크면 탐색을 종료함 ''' if depth > 3: # get_url() 호출은 depth를 3단계 까지만 수행하도록 제한 return None links = [] html = get_download(link) dom = BeautifulSoup(html.text, "lxml") for a in dom.select("a"): if a.has_attr("href"): if a["href"].startswith("http"): # externalLink : HTTP(S) links.append({"url": a["href"], "depth": depth + 1}) elif a["href"].startswith("/"): # internalLink : / href = urljoin(link, a["href"]) links.append({"url": href, "depth": depth + 1}) else: # print("Skipped: {0}".format(a["href"])) pass print("{0} {1} --> {2}개 사이트 추가".format(">" * (depth + 1), link, len(links))) return links
def get_naver_title(search_string=None): ''' 이 함수는 네이버에서 지정한 문자열을 검색 후 검색결과 중 제목 List를 Return 합니다. naver 검색결과는 class명이 "main_pack"인 <div> 태그 하부에 존재 합니다. 검색결과 우측의 뉴스토픽은 class명이 "sub_pack"인 <div> 태그 내에 존재 합니다. 검색결과는 블로그, 카페, 동영상, 뉴스, 지식인, 웹사이트, 이미지 섹션으로 구분되어 있고, 동영상, 이미지 섹션을 제외하고는 공통적으로 <ul> 태그의 class명이 "type01" 이고, <ul> 태그 아래 <li> 태그 내에 세부 리스트가 있습니다. 블로그 만 검색하려면 class명 "sh_blog_top"를, 카페 만 검색하려면 class명 "sh_cafe_top"를 사용할 수 있습니다. 검색결과 리스트의 제목은 <ul> - <li> - <dl> - <dt> - <a> 태그 구조로 되어 있고, <a> 태그의 text가 제목 문자열 입니다. "type01" class를 찾은 후, <dt> 태그 내에 있는 <a> 태그의 text를 찾으면 됩니다.(<a> 태그를 바로 찾으면 불필요한 내용이 포함됩니다.) search_string : 검색할 문자열(String) return 값은 섹션별로 제목 리스트를 포함하고 있는 List(2차원 배열) 입니다. ''' html = get_download(naver_url, params={"query": search_string}) dom = BeautifulSoup(html.text, "lxml") ulTags = dom.find_all("", {"class": "type01"}) result = [] for ul in ulTags: section = [] for dt in ul.find_all("dt"): section.append(dt.a.text.strip()) result.append(section) return result
def get_google_title_with_url(search_string=None): ''' 이 함수는 구글에서 지정한 문자열을 검색 후 검색결과 중 제목과 URL List를 Return 합니다. google 검색결과를 분석해보면, 제목 바로 위에 있는 div 태그의 class명이 "r"로 일정한 것을 발견할 수 있습니다. <h3 class="r"> 태그 하부에 <a> 태그의 text 부분에 제목이 보입니다. <a> 태그의 text에는 제목과 URL이 함께 표시되기 때문에 제목 만 가져오기 위해서는 <a> 태그 내에 있는 <h3> 태그의 text 만을 가져오면 됩니다. URL은 <a> 태그 내에 있는 "href" 속성을 가져오면 됩니다. search_string : 검색할 문자열(String) ''' html = get_download(google_url, params={"q": search_string}) dom = BeautifulSoup(html.text, "lxml") tags = dom.find_all("div", {"class": "r"}) result = [] for tag in tags: title = tag.find("a").h3.text.strip() url = tag.find("a").get("href") result.append([title, url]) return result
def get_portal_to_dom(search_string=None): ''' 구글, 네이버, 다음 포탈에서 특정 문자열을 검색한 결과를 DOM 객체 List로 반환 합니다. portal: "google", "g", "naver", "n", "daum", "d" 중 하나를 지정(default는 "google") search_string: 검색할 문자열(String) ''' google_html = get_download(google_url, params={"q": search_string}) naver_html = get_download(naver_url, params={"query": search_string}) daum_html = get_download(daum_url, params={"q": search_string}) nate_html = get_download(nate_url, params={"q": search_string}) google_dom = BeautifulSoup(google_html.text, "lxml") naver_dom = BeautifulSoup(naver_html.text, "lxml") daum_dom = BeautifulSoup(daum_html.text, "lxml") nate_dom = BeautifulSoup(nate_html.text, "lxml") return (google_dom, naver_dom, daum_dom, nate_dom)
def download(self, default_path="naver_news"): ''' 기사 다운로드 후 본문을 저장하고, 기사 랭크, 제목, url을 csv 파일로 저장합니다. 기사 저장 파일명은 category_code(00~05) + "-" + rank(00~09) + "-" + aid + ".txt" 형태로 저장합니다. csv 파일명은 "newslist-" + path + ".csv" 형태로 저장합니다. return : 뉴스 기사 리스트를 3차원 배열(섹션, 기사, 랭크/제목/링크)로 반환 합니다. ''' self._get_categorys() self._get_newslists() self._make_savedir(default_path=default_path) print("뉴스 기사 다운로드 중...") for idx, section in enumerate(self._newslists): # 파일명에 사용할 카테고리 이름 가져오기 # idx = self._newslists.index(section) cat_code = self._category_codes[self._category_names[idx]] # 기사 다운로드 하고 가져오기 for sec in section: # sec[0]에 rank, sec[1]에 기사 제목, sec[2]에 기사 링크가 있음 html = get_download(sec[2]) dom = BeautifulSoup(html.text, "html.parser") contents = dom.select("#articleBodyContents")[0] # content에 <script> 태그 내의 내용이 포함되어 있음 # (삭제할 필요는 없음. 삭제하지 않으려면 위에 코멘트 처리된 부분을 사용) contents_ = contents.text.replace( "// flash 오류를 우회하기 위한 함수 추가\nfunction _flash_removeCallback() {}", "") # 기사 url에 포함된 article ID(aid) 값을 추출해서 file명에 사용 aid = re.findall(r"aid=\d+", sec[2])[0].split("=")[1] rank = sec[0] fileName = cat_code + "-" + self._ranks[ rank] + "-" + aid + ".txt" fullPath = os.path.join(self._path, fileName) with open(fullPath, "w") as f: f.write(contents_) csvFileName = os.path.join( default_path, "newslist-" + self._path.split("/")[-1] + ".csv") df = pd.DataFrame(np.array(self._newslists).reshape(-1, 3)) df.to_csv(csvFileName, header=False, index=False) print("{0} 폴더에 뉴스 기사 다운로드 완료".format(self._path)) return self._newslists
def get_nate_title_with_url(search_string=None): ''' 이 함수는 네이트 포탈에서 문자열을 검색 후 검색결과 중 제목과 URL List를 Return 합니다. (편의상 블로그 검색 결과만 Return 합니다.) URL은 <a> 태그 내에 있는 "href" 속성을 가져오면 됩니다. search_string: 검색할 문자열(String) ''' html = get_download(nate_url, params={"q": search_string}) dom = BeautifulSoup(html.text, "lxml") result = [] blog = dom.find("", {"id": "blogColl"}) for tag in blog.find_all("a", {"class": "f_link_b"}): title = tag.text.strip() url = tag["href"] result.append([title, url]) return result
def get_nate_title(search_string=None): ''' 이 함수는 네이트 포탈에서 문자열을 검색 후 검색결과 중 제목 List를 Return 합니다. (편의상 블로그 검색 결과만 Return 합니다.) 네이트는 다음 검색을 이용합니다. 블로그 검색 결과는 id가 "blogColl"인 <div> 태그 하부에 존재 합니다. <a> 태그의 class명 "f_link_b" 내에 제목이 있습니다. search_string: 검색할 문자열(String) ''' html = get_download(nate_url, params={"q": search_string}) dom = BeautifulSoup(html.text, "lxml") result = [] blog = dom.find("", {"id": "blogColl"}) for tag in blog.find_all("a", {"class": "f_link_b"}): result.append(tag.text) return result
def get_site(self, page): self.param["page"] = page html = get_download(self.movie_point_url, params=self.param) dom = BeautifulSoup(html.text, "html.parser") return dom