0. 시작하기 전 잡소리

교외근로 하는 곳에서 특정 사이트에서 (특정 인물의) 사진을 긁어달라는 요청을 받았다.
사실 필요한 수가 적으면 손으로 일일히 해도 되지 싶었는데, 중복을 제외하고 5천장이 필요하다는 말씀을 하시더라
이걸 맨손으로 직접 긁다가는 정신 놓겠다는 생각에 일단 헤딩해보기로 햇따



1. 어떻게 긁어올까 (1)

남들이 만들어둔 파이썬 크롤러를 가져다가 쓰면 되지 않을까라는 막연한 생각으로 검색을 시작했다.
icrawler가 구글 검색 결과랑 그 외에 몇 가지를 더 지원하길래 이걸로 구글 검색 결과를 다 긁어오면 끝일줄 알았는데....
구글에서 최대 검색 결과를 1000개로 제한해서 한 번에는 5천개를 채울 수 없었다. 이외에도 인물 사진이 아니라 특정 인물이 생전에 사용하던 빗이나 장화 같은게 같이 잡혀버리는 문제도 있었고...


장화는 우리한테 필요가 없다...


사실 1천개 제한에 걸리기 이전에, 검색에서 잡히는 이미지가 900개 남짓이라서, 5천개를 전부 구하려면 결국 사이트에서 직접 긁어와야 했다. 



다행히도, 이미지를 긁어달라고 요청 받은 사이트는 사진 자료들만 따로 모아서 볼 수 있는 페이지를 제공했다.




icrawler에 내장된 GreedyImageCrawler가 사이트에 img 태그가 달린 모든 파일을 뽑아내서, 해상도 상 / 하한선을 정해 크롤링할 수 있어서 이걸 그대로 쓰려고 했으나...
이렇게 하면 해상도가 낮은 썸네일용 이미지를 긁어오게 되는 문제도 있고, 사료 페이지 하나에 이미지가 여러 개 등록된 글의 이미지를 올바르게 긁어오지 못한다는 문제가 있었다. 




2. 어떻게 긁어올까 (2)

사진 자료들이 등록된 게시글 번호가 연속적이었으면 시작과 끝만 찾는 걸로 해결될 일이었지만, 2천번대, 4천번대, 2백만 등 연속적이지 않았기에 사진 자료가 있는 게시글 번호만 알아낼 방법이 필요했다.
사진 자료를 조회하는 페이지에서 각 페이지의 제목이 연결하는 링크를 긁어내고, 그 링크로 들어가서 본문에 이미지가 있다면 그 이미지 주소를 다 긁어낸 다음, icrawler한테 주면 얘가 알아서 긁겠지 라는 생각으로 BeautifulSoup를 이용해보기로 했다.


import requests
from bs4 import BeautifulSoup

f = open("url_list.txt", 'a')
target_url = 'http://archives.knowhow.or.kr/record/image/list/'
dest_url = 'http://archives.knowhow.or.kr'

for page_number in range(1, 1377):
    req = requests.get(target_url + str(page_number))
    html = req.text
    soup = BeautifulSoup(html, 'html.parser')

    my_urls = soup.select(
        'li > p:nth-child(2) > span > a'
    )
    for url in my_urls:
        data = dest_url + url.get('href') + "\n"
        f.write(data)

f.close()


글 제목이나 썸네일 사진, 본문 중 a 태그의 href 속성이 각 사료로 향하는 주소를 담고 있다. BeautifulSoap를 이용해, 각 페이지에서 글 제목의 a 태그를 뽑아내고, href를 온전한 URL로 만들어서 텍스트 파일로 저장한다.


import requests
from bs4 import BeautifulSoup

f = open("url_list.txt", 'r')
f2 = open("file_list.txt", 'a')

while True:
    line = f.readline()
    if not line: break
    
    req = requests.get(line)
    html = req.text
    soup = BeautifulSoup(html, 'html.parser')

    file_number = soup.select(
        '.tomatoGallery > tbody > tr > td > img'
    )

    for file in file_number:
        data = file['src'] + "\n"
        f2.write(data)

f.close()
f2.close()



만들어진 URL로 사료 보기 페이지에 접속하면, 한 장 또는 여러 장의 사진이 페이지에 있는데, 썸네일 사진이 아닌 본문 사진들의 img 태그를 뽑아내어, src를 알아내어 각 사진 파일의 주소를 얻는다.


from icrawler.builtin import UrlListCrawler urllist_crawler = UrlListCrawler(downloader_threads=8, storage={'root_dir': 'D:\iCrawler'}) urllist_crawler.crawl('file_list.txt', max_num=17936)


icrawler를 통해 사진 파일의 주소에 있는 사진 파일을 다운받는다.

(max_num = 17936은 file_list.txt에 있는 파일의 개수를 다운로드 받을 파일 개수의 상한선으로 지정한 것이다.)





구도가 비슷한 사진을  추려내고도, 5천장보다 훨씬 많은 사진을 확보할 수 있었다.

'etc' 카테고리의 다른 글

코드 하이라이팅 테스트  (0) 2018.10.03

+ Recent posts