HTML

<td>
    {% if ids %}
        {% for m in ids %}
            <a href="/merchant/{{m.id}}/" target=_blank>{{m.name}}</a>
        {% endfor %}
    {% else %}
        연결된 가맹점이 없습니다.<br>
        {% if w|slice:":2" != '01' %}
            <button class="btn btn-info btn-search" data-phone="{{ w }}">웹에서 검색하기</button>
        {% endif %}
    {% endif %}
</td>

<script>
$(document).ready(function () {
    $('.btn-search').on('click', function () {
        if($(this).attr('aria-describedby') === undefined){
            crwaling_merchant_info($(this).data('phone'), $(this));
        }else{
            var popover_id = $(this).attr('aria-describedby');
            $('#'+popover_id).remove();
            $(this).removeAttr('data-original-title title aria-describedby');
        }
    })
});
</script>

핸드폰번호로 웹에서 검색을 할경우 상호명등이 나오지 않으므로 templatefilter slice를 이용해 01로 시작하는 번호는 검색기능을 넣지 않음

JS

function crwaling_merchant_info(phone, ele) {
    $.ajax({
        url: '/ajax/crwaling_merchant_info/',
        type: 'post',
        dataType: 'json',
        data: {
            phone: phone
        },
        cache: false,
        async: true,
        success: function (json) {
            if (!json['success']){
                alert('처리 중 오류가 발생하였습니다.');
                $(ele).removeAttr('disabled');
                return false;
            }
            $(ele).popover({
                title: json['merchant']['name'],
                content: json['merchant']['address']
            }).popover('show').removeAttr('disabled');
            return true;
        },
        error: function (err) {
            $(ele).popover({
                content: '해당 번호에 대한 정보를 찾을 수 없습니다.'
            }).popover('show').removeAttr('disabled');
        },
        beforeSend: function () {
            $(ele).attr('disabled', true);
        }
    })
}

오류 발생시 alert를 발생하며 button의 disabled attr 제거

성공시 popover를 통해 가게 이름과 주소를 보여줌

crawling 메서드

def phone_crawler(phone):
    naver_params = {
        'sm': 'mtb_hty.top',
        'where': 'm',
        'query': phone,
    }
    headers = {'Referrer': 'always'}
    naver_search_url = 'https://m.search.naver.com/search.naver?' + urllib.urlencode(naver_params)
    naver_response = requests.get(naver_search_url, headers=headers)
    naver_soup = BeautifulSoup(naver_response.text, "html.parser")
    print(naver_response)
    naver_parse_data = naver_soup.select_one('.item_info')
    if naver_parse_data:
        merchant = {
            "name": naver_parse_data.select_one('span.tit').get_text().encode('utf-8'),
            "address": naver_parse_data.select_one('span.address').get_text().encode('utf-8'),
        }
        return merchant
    daum_params = {
        'w': 'tot',
        'nil_mtopsearch': 'btn',
        'DA': 'YZR',
        'q': phone,
    }

    daum_url = 'https://m.search.daum.net/search'
    daum_search_url = daum_url + "?" + urllib.urlencode(daum_params)
    daum_response = requests.get(daum_search_url)
    daum_soup = BeautifulSoup(daum_response.text, "html.parser")

    daum_parse_data = daum_soup.select_one('div.coll_cont')
    if daum_parse_data:
        merchant = {
            "name": daum_parse_data.select_one('.txt_name').get_text().encode('utf-8'),
            "address": daum_parse_data.select_one('#poiAddressLabel').get_text().encode('utf-8'),
        }
        return merchant

    return None


네이버 검색시 header안에 refferer를 넣어야 함 안넣을 경우 403에러 발생

네이버에 요청을 하여 data를 파싱하여 값을 넣고 리턴을 하며 값이 없을 경우 daum쪽에 검색을 한다.

리턴된 값은 crwaling_merchant_info의 merchant값으로 전달되어 popover로 나타난다.

결과

info_crawaling_from_number

추가

해당 데이터를 client단에 cache화 하여 과하게 많은 요청을 보내지 않도록 수정 필요

Celery 데몬화

# Celery 데몬으로 관리하기### Celery 설정파일 작성하기```# vi /srv/celery/celery.confCELERYD_NODES="worker1"CELERY_BIN="/home/ubuntu/.pyenv/versions//bin...… Continue reading

EC2 배포 설정

Published on May 18, 2020