활용3. 웹스크래핑(0825-0829)/requests

스크래핑 2-1 쿠팡 (User-Agent 헤더)

나도초딩 2022. 8. 28.

쿠팡 실습

헤더옵션에 User-Agent 외 추가 정보 필요.

문제는 헤더옵션만으로도 접속이 안돼서, 거의 하루 순삭하고, 스트레스 이뽜이. 답도 쉽게찾기가 어려웠다. ㅠ
( 이런 문제 하나 발생하면, 하루 순삭 ㅠ )

 

이를 제외하면, 접속트러블만 없다면, 쉽지만 뿌듯한 예제 (대형사이트는 접속이 문제긴 하다. ㅠ )

  1. soup.find_all 에서 블록을 선택시, 반복하는 가장 상위 객체를 선택하기.
  2. re.compile() 사용 : 이 예시에서는 필수적이지 않음
  3. 페이지 반복 --> in range(1,6)
  4. enumerate 함수 사용
  5. if 조건문 : 텍스트 포함과 참/거짓
import requests
from bs4 import BeautifulSoup
import re

# headers = {
#     "Accept-Language": "en-US,en;q=0.9",
#     "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
# }
# headers = { 
#		"Accept-Language": "en-US,en;q=0.9", 
#		"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36", 
#		#"X-Amzn-Trace-Id": "Root=1-60ff12bb-55defac340ac48081d670f9d" 
#	} 

# 1-6 페이지까지 전체 반복시키기. 
for i in range(1,6):
    URL = "https://www.coupang.com/np/search?q=%EB%85%B8%ED%8A%B8%EB%B6%81&channel=user&component=&eventCategory=SRP&trcid=&traid=&sorter=scoreDesc&minPrice=&maxPrice=&priceRange=&filterType=&listSize=36&filter=&isPriceRange=false&brand=&offerCondition=&rating=0&page={}&rocketAll=false&searchIndexingToken=1=6&backgroundColor=".format(i)

    res = requests.get(URL, headers=headers)
    res.raise_for_status()
    soup = BeautifulSoup(res.text, "lxml")

    items = soup.find_all("li", attrs={"class":re.compile("^search-product")})
    for i,item in enumerate(items):
        # ad-badge-text
        if item.find("span",{"class":"ad-badge-text"}) :
            continue
        
        
        price = item.find("strong", {"class":"price-value"})
        if price:
            price = price.get_text()
        else:
            price = "0"
        #리뷰수
        rate = item.find("span",{"class":"rating-total-count"})
        if rate:
            rate = rate.get_text()[1:-1]
        else:
            rate = "0"
            
        prod_name = item.find("div", {"class":"name"}).get_text()
        if "HP" in prod_name:
            continue
        
        link = item.a["href"]

        if (int(rate) > 10) and ("2022" in prod_name):
            print(f'{i+1}. {price} : 리뷰수 : {rate} - {prod_name.strip()[:10]}  http://coupang.com{link}')
        

# print(soup)

 


서버에서 접속 차단될 때,

User-Agent 옵션을 넣는데,

대형 쇼핑몰들은 크롤과의 전쟁이 있어서 이것만으로 안되는 경우도 많다.

 

제대로 된 지침이 잘 안보여서 영어로 검색하다가 발견했다

https://www.zenrows.com/blog/stealth-web-scraping-in-python-avoid-blocking-like-a-ninja#user-agent-header

 

Mastering Web Scraping in Python: Avoid Detection Like a Ninja - ZenRows

Learn how to scrape any website without getting blocked or blacklisted while bypassing anti-bot solutions and CAPTCHAs.

www.zenrows.com

많은 양의 크롤이 감지될 경우, ip 가 차단되는 경우도 있고, --> proxy 등 ip 우회

User-Agent 를 랜덤으로 여러가지로 접속시키기

이건 추후 블락이 됐거나, 블락을 염두에 둔 것이고,

연습용으로는 접속이 되야하니, header에 User-Agent 외 몇 가지 정보를 더 제공해본다.

 

https://httpbin.org/headers

 

손마사요시가 투자한 쇼핑몰의 경우 , User-Agent 외에, Accept-Language 나 session-id 등을  추가해줘야 했다. ( 2022.8.28 기준 )

"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",

 

https://www.dbility.com/538

dummy_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

dummy_cookies = {
    'session-id': '139-6087491-2828334',
    # 'session-id-time': '2082787201l',
    # 'i18n-prefs': 'USD',
    # 'sp-cdn:'"L5Z9:KR"','
    # 'skin': 'noskin',
    # 'ubid-main': '130-2421179-7560556',
    # 'session-token': 'nV0slBNZnFCnT+35eEZR01v7Xv69aoVRefqNnlR+AxMTQeaJxc318UcfuWmAGc3vqFAmMxNypUUmEPF0acnUnwhaXip+MmqLrbBx50eKTbM2valdSiYhSdFhnYgC9+MjtcBNeGM49jTQSRhCTJMmY/kgsODPXPNtRbr9VeDD5EDkNFYMpL2AHJxyJ0ACeqUD7OfpgT2gDYZnffhJWL9Ai/iQWJiKCpod9IqwePrrt+LJTmHRSHqO6AL6UaHonJcF',
    # 'csm-hit': 'tb:4PH14D8R1NFG06S7WSKG+s-22X053BHG853AXRQ8YYW|1629357378020&t:1629357378020&adb:adblk_no'
}
req = requests.get('https://coupang.com', headers=dummy_headers,
                   cookies=dummy_cookies)
req.raise_for_status()

if req.status_code == 200:
    try:
        soup = BeautifulSoup(req.content, 'html.parser')
        print(soup)
               
    except:
        print('Error.............')
else:
    print('Error', req.message)

 

기타

User-Agent 를 random.choice 로

import requests 
import random 
 
user_agents = [ 
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 
	'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36', 
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36', 
	'Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148', 
	'Mozilla/5.0 (Linux; Android 11; SM-G960U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Mobile Safari/537.36' 
] 
user_agent = random.choice(user_agents) 
headers = {'User-Agent': user_agent} 
response = requests.get('https://httpbin.org/headers', headers=headers) 
print(response.json()['headers']['User-Agent']) 
# Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) ...

Full set header 샘플

headers = { 
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "en-US,en;q=0.9", 
    #"Host": "httpbin.org", 
    "Sec-Ch-Ua": "\"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"92\"", 
    "Sec-Ch-Ua-Mobile": "?0", 
    "Sec-Fetch-Dest": "document", 
    "Sec-Fetch-Mode": "navigate", 
    "Sec-Fetch-Site": "none", 
    "Sec-Fetch-User": "?1", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36", 
    #"X-Amzn-Trace-Id": "Root=1-60ff12bb-55defac340ac48081d670f9d" 
}

댓글