지마켓  컴퓨터/가전 부분 베스트 상품 타이틀과 가격 추출하기

 

import requests

from bs4 import BeautifulSoup

 

res = requests.get('http://corners.gmarket.co.kr/Bestsellers?viewType=G&groupCode=G06') : 어디에서 어떻게 페이지 주소가 달라지는지도 유심히 보기

soup = BeautifulSoup(res.content, 'html.parser')

 

bestitem = soup.select('div.best-list li')  : 집합 관계에서 A에 대한 abc추출, B에 대한 abc추출 이렇게 하려면 크게 A B C ... 를 추출한 후에 각각에서 abc를 뽑아내야 하기 때문에 상하위 구조 잘 보고 태그 결정하기

 

for i in bestitem :

    name = i.select_one('a.itemname')

    price = i.select_one('.item_price strong')  : 가격이라도 정가, 세일가 등등 다를 수 있으므로 공통되는 것이 뭔지 정확히 알기

    print(name.get_text() , price.get_text())

 

 

상품 상세 페이지의 판매업체까지 추출하기

 

import requests

from bs4 import BeautifulSoup

 

res = requests.get('http://corners.gmarket.co.kr/Bestsellers?viewType=G&groupCode=G06')

soup = BeautifulSoup(res.content, 'html.parser')

 

bestitem = soup.select('div.best-list li') 

 

for i in bestitem :

    name = i.select_one('a.itemname')

    price = i.select_one('.item_price strong')

    res_info = requests.get(name['href'])  : name태그 하위에 각 상세페이지 주소 있고, 그거 가져오려면 ['하위태그']

    soup_info = BeautifulSoup(res_info.content, 'html.parser')

    seller = soup_info.select_one('span.text__seller > a')

    print(name.get_text() , price.get_text(), seller.get_text())

 

 

엑셀 파일로 정리하기

 

import requests

from bs4 import BeautifulSoup

import openpyxl

 

 

 

 

 

 

 

 

 

 

특별한 패턴을 가진 데이터를 삭제하거나 변환, 추출해야 하는 경우, 정규표현식을 활용

 

정규 표현식 축약 표현 설명
[0-9] \d 숫자
[^0-9] \D 숫자 제외
[ \t\n\r\f\v] \s white space(스페이스, 탭, 엔터, )
[^ \t\n\r\f\v] \S white space 제외
[a-zA-Z0-9] \w 영어, 숫자
[^a-zA-Z0-9] \W 영어, 숫자 제외

 

표현 설명
[.]  or  \. 문자 딱 한 개 (줄바꿈 제외)
? 앞 문자가 0번 또는 1번
* 앞 문자가 0번 이상
+ 앞 문자가 1번 이상
{n} 앞 문자가 n번 반복
{m,n} 앞 문자가 m번~n번 반복  _ {m, n}으로 띄어쓰기 불가능
[abc] 개별 문자 a,b,c 중 하나라도
[가-힣] 한글 전체

전체 문자열과 똑같은 지가 아니라

전체 문자열중에 해당 패턴이 있는지를 확인해서 출력

 

 

 

import re  : 정규표현식 함수를 포함한 라이브러리

 

정규표현식 패턴 만들기

패턴변수 = re.compile('어쩌구')

 

대체하기

sub : 데이터에서 특정 패턴을 찾아서 바꾸는 것

re.sub(정규표현식, 바꿀문자열, 원래문자열)

소문자/대문자 구별 o

subed = 패턴변수.sub(바꿀문자열, 원래문자열)

 

패턴 매칭 확인하기

패턴변수.match("매칭할 텍스트")   : 처음부터 매칭되어야 리턴

패턴변수.search("매칭할 텍스트")   : 어느 한 부분이라도 만족하면 리턴

패턴변수.findall("매칭할 텍스트")   : 매칭되는 모든 부분을 스페이스로 구분해 리스트로 리턴

 

분리하기

패턴변수 = re.complie('어쩌구')

문자열변수 = 패턴변수.split( '~~어쩌구~~' )

어쩌구 앞뒤로 분리해 리스트로 리턴

 

 

정규표현식으로 나타낼 형식에 []가 있으면

정규표현식 [형식] 의 []과 겹치기 때문에

이럴 때에는 \ 역슬래시로 쓰기

 

re.sub('\[[0-9]+\]

 

 

JSON 포맷

 

JSON이란?

JavaScript Object Notation

웹 환경에서 서버와 클라이언트 사이에 테이터를 주고 받을 때 Rest API

형식 _ { "키" : "값" , "키" : "값" , ... }

 

0. 없으면 설치하기  )   pip install json

1. 라이브러리 가져오기  )   import json

2. 데이터 입력하기  )   data = """

                                     { 

                                        json포맷

                                      }

                                      """

3. 데이터 파싱하기  )   json_data = json.loads (data)     _ loads(문자열) : 문자열 파싱

4. 읽기  )   print( json_data[키이름][인덱스번호] ... )

 

import json

# 네이버 쇼핑에서, android 라는 키워드로 검색한 상품 리스트 결과
data = """
{
    "lastBuildDate": "Sat, 22 Jun 2019 14:57:13 +0900",
    "total": 634151,
    "start": 1,
    "display": 10,
    "items": [
        {
            "title": "MHL 케이블 (아이폰, <b>안드로이드</b> 스마트폰 HDMI TV연결)",
            "link": "https://search.shopping.naver.com/gate.nhn?id=10782444869",
            "image": "https://shopping-phinf.pstatic.net/main_1078244/10782444869.5.jpg",
            "lprice": "16500",
            "hprice": "0",
            "mallName": "투데이샵",
            "productId": "10782444869",
            "productType": "2"
        },
        {
            "title": "파인디지털 파인드라이브 Q300",
            "link": "https://search.shopping.naver.com/gate.nhn?id=19490416717",
            "image": "https://shopping-phinf.pstatic.net/main_1949041/19490416717.20190527115824.jpg",
            "lprice": "227050",
            "hprice": "359000",
            "mallName": "네이버",
            "productId": "19490416717",
            "productType": "1"
        }
    ]
}
"""

json_data = json.loads(data)
print (json_data['items'][0]['title'])
print (json_data['items'][0]['link'])

 

 

JSON 포맷으로 크롤링하기

 

< 기본 형식 >

 

import requests

 

client_id = '아이디'

client_secret = '시크릿'

 

naver_open_api = ' 요청 url '

 

headers_params = { 'X-Naver-Client-Id' : 'client_id' , 'X-Naver-Client-Secret' : 'client_secret' }

 

res = requests.get( naver_open_api , headers = header_params )

 

if res.status.code == 200 :

    data = res.json()

    print(data)    or    for i in data['items'] :

                                    print( i['title'] )

else :

    print( 'Error code : ' , res.status_code )

 

 

< 1000개 출력해서 엑셀로 저장하기 >

 

import requests

import openpyxl

 

client_id = '아이디'

client_secret = '시크릿'

start, num = 1 , 0

 

excel_file = openpyxl.Workbook()

excel_sheet = excel_file.active

excel_sheet.column_dimensions['B'].width = 100

excel_sheet.column_dimensions['C'].width = 100

excel_sheet.appen( ['랭킹' , '제목' , '링크'] )

 

for index in range(10) :

    start_number = start + (index * 100)

    naver_open_api = ' 요청 url  ... ? query=키워드 & display=100 & start= ' + str(start_number)

                                                         키워드가 들어간 페이지를    100개씩                특정 번호부터

    header_params = { 'X-Naver-Client-Id' : client_id , 'X-Naver-Client-Secret' : client_secret }

    res = requests.get ( naver_open_api , headers = header_params )

    

    if res.status_code == 200 :

        data = res.json()

        for i in data['items'] :

            num += 1

            excel_sheet.append( [num , item['title'] , item['link'] ] )

    else :

        print( "Error Code : ", res.status_code )

 

excel_file.save( '파일이름.xlsx')

excel_file.close()

 

 


 

XML 포맷

 

XML 이란?

Extensivle Markup Language

Html과 같이 태그 형태로, bs4 BeautifulSoup 사용

 

형식 )  < 태그명  속성명='속성값' >  내용  < /태그명 >

 

단, css 아니므로 select 아닌 find로 파싱하기

 

 

XML 포맷으로 공공데이터 크롤링하기

 

import requests

from bs4 import BeautifulSoup

 

service_key = ' 서비스키 '

params = ' &키=값&키=값&...'

open_api = ' 요청 url  ?ServiceKey=' + service_key + params     _ 네이버는 헤더 정보를 headers에

                                                                                                          공공데이터는 주소에 쓰게끔 설정되어 있음

res = requests.get(open_api)

soup = BeautifulSoup(res.content , 'html.parser')

 

data = soup.find_all('item')

for i in data :

    stationname = item.find('stationname')

    print( stationname.get_text() )

 

 

Open API / Rest API란?

 

# API (Application Programming Interface) 

: 특정 프로그램을 만들기 위해 제공되는 함수 등의 모듈

 

# Open API

: 누구나 사용할 수 있도록 공개된 API로,

  주로 Rest API 기술을 사용해 주소를 만들어 공개

 

# Rest API (Representational State Transfer API)

: Http 프로토콜을 통해 서버를 제공하는 함수로,

  주로 JSON, XML의 형태로 응답을 전달

 

 

 

 

네이버 Open API 활용하기

https://developers.naver.com/main/

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

애플리케이션 등록해서 Client ID / Secret 받기

Documents - 서비스 API - 검색 에서 요청 url 받기

 

 

 

 

Postman 활용하기

 

1. Request

2. get에 요청할 url 입력 

   - 네이버 Developers 사이트의 Documents - 서비스 API - 검색 에서 알맞은 요청 url 복사

   - 형식 ) 요청 url + ? + 요청변수 = 어쩌구 & 요청변수 = 어쩌구

                  ex. https://openapi.naver.com/v1/search/shop.json?query=샤오미&display=100

3. headers에 key와 value 입력

    [key]                                [value]

    X-Naver-Client-Id            아이디

    X-Naver-Clinet-Secret     시크릿

  

    http의 틀에는 맨 앞에 헤더 정보 / 바디에는 주소 정보가 담겨져서 전송되는데,

    주소만 쓰면 헤더는 디폴트값으로 전송되며, headers에 key와 value 입력해서 정보 추가 가능

 

 

 

 

 

엑셀 활용 라이브러리 사용법

 

0. 라이브러리 없으면 설치하기  )   터미널 모드에서  pip install openpyxl

 

1. 라이브러리 불러오기  )   import openpyxl

 

2. 엑셀 파일 만들기  )   excel_file = openpyxl.Workbook()

 

3. 디폴트 시트 활성화하기  )   excel_sheet = excel_file.active

                                                excel_sheet.title = '시트 이름'

 

4. 데이터 추가하기  )   리스트 하나가 한 행으로 추가

                                     excel_sheet.append( ['data1' , 'data2' , 'data3'] )

 

5. 엑셀 파일로 저장하고 닫기  )   excel_file.save('엑셀파일이름.xlsx')

                                                     excel_file.close()

                                                             ↳ 파일 닫기 안해주면 리소스가 계속 활성화되어 있으므로 닫아주기!

 

 

 

함수로 엑셀파일 만들기

 

import openpyxl

 

def create_excel ( filename, sheetname, listdata ) :

    excel_file = openpyxl.Workbook()

    excel_sheet = excel_file.active

    

    if sheetname != '' :

        excel_sheet.title = sheetname

 

    for i in listdata :

        excel_sheet.append( i )

     

     excel_file.save(filename)

     excel_file.close()

 

 

 

크롤링 후 함수 사용하기

 

import requests

from bs4 import BeautifulSoup

 

product_lists = list()

 

for page_num in range(10) :

    if page_num == 0 :

        res = requests.get('~주소~')

    else :

        res = resquests.get( '~주소~' + str(page_num + 1) )

    soup = BeautifulSoup( res.content , 'html.parser' )

    data = soup.select('상위 태그')

    for i in data :

        product_name = i.select_one( '상품명태그' )

        product_data = i.select_one( '일자태그' )

        product_info = [ product_name.get_text() , product_data.get_text() ]     _ [상품명, 일자] 리스트 만들기

        product_lists.append( product_info )     _ 리스트 내 리스트 만들기

 

create_excel( '엑셀파일이름.xlsx' , '시트이름' , product_lists)

 

 

 

엑셀 파일 읽기

 

1. 라이브러리 가져오기  )   import openpyxl

 

2. 엑셀 파일 열기  )   excel_file = openpyxl.load_workbook( '엑셀파일이름.xlsx' )

                                  ↳ 해당 폴더 안에 있는 파일이어야 함

 

3. 시트 선택하기  )   

 

- 시트 이름 확인 :  excel_file.sheetnames     _ 시트 이름이 리스트 형태로 반환

- 특정 시트 선택 :  excel_sheet = excel_file[ '시트이름' ]

- 시트가 하나뿐 :  excel_sheet = excel_file.active

 

4. 데이터 읽기  )   for row in excel_sheet.rows     _ 행을 리스트 형태로 row에 대입

                                  print( row[0].value , row[1].value )

 

5. 파일 닫기  )   excel_file.close()

 

 

 

+ 셀 사이즈 조정하기

 

excel_sheet . column_dimention['A'].width = 100     _ A셀의 넓이를 100으로 조정

 

 

 

 

 

 

1. HTTP란

 

클라이언트가 네트워크를 요청하고

서버가 그에 맞는 네트워크를 전송할 때

HTTP라는 프로토콜 규격에 맞게 공유해야 함 !

 

 

2. HTTP 응답코드

 

응답코드 response code

 

웹브라우저가 프로토콜 규격을 파싱해서 특정 부분에서 html 데이터를 가져오고

전송할 때 html과 함께 응답코드(response code)를 같이 보내는데,

 

200번대면 정상, 400번대면 오류

 

https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

 

HTTP 상태 코드 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 아래는 HTTP(하이퍼텍스트 전송 프로토콜) 응답 상태 코드의 목록이다. IANA가 현재 공식 HTTP 상태 코드 레지스트리를 관리하고 있다. 모든 HTTP 응답 코드는 5개의

ko.wikipedia.org

 

응답코드 확인 방법

 

: requests 라이브러리의  requests.get() 의 변수 .status_code

 

⇒ 응답코드가 오류일 경우 크롤링을 하지 않도록 하려면

 

res = requests.get( '웹페이지 주소' )

if res.status_code != 200 :

    print('페이지 없음')

else :

    soup = BeautifulSoup( res.content, 'html.parser')

    ~~~

 

 

 

 

+ Recent posts