전공 과목 이수1👨‍💻/파이썬

크롤링 - 유튜브 5시간짜리 보고 정리

천숭이 2021. 12. 3. 01:03

https://www.youtube.com/watch?v=yQ20jZwDjTE 

 

 

# Requests

import requests
res=requests.get("http://naver.com")
res=requests.get("http://ccssbb.tistory.com")
res.raise_for_status()  # 이상하면 오류발생시키기
print(res.status_code)

# if res.status_code == requests.codes.ok:  # 상태코드가 200이면
#     print("정상입니다")
# else:
#     print("문제가 생겼습니다")

print(len(res.text))

with open("mygoogle.html","w",encoding="utf8") as f:  # mygoogle 파일 생성된다.
    f.write(res.text)

 

# re 정규식

- group() : 일치하는 문자열 반환

- string : 입력받은 문자열

- start() : 일치하는 문자열의 시작 index

- end() : 일치하는 문자열의 끝 index

- span() : 일치하는 문자열의 시작 / 끝 index

- findall() : 일치하는 모든 것을 리스트 형태로 반환

 

1. p = re.compile("원하는 형태")

2. m = p.match("비교할 문자열")

3. m = p.search("비교할 문자열")

4. lst = p.findall("비교할 문자열")

 

- 원하는 형태 : 정규식

# 점 (.)  : 하나의 문자를 의미
# ^       : 문자열의 시작
# $ (se$) : 문자열의 끝   ex) case, base
 

정규식 참고 사이트 (정규식외에도 정보가 많음)

 

Python RegEx

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com


# user agent

구글 검색창에 what is my user agent 라고 검색하면 내 agent를 알려준다.

- 접속하는 브라우저에 따라 에이전트가 다르다

import requests
from bs4 import BeautifulSoup

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=1&rocketAll=false&searchIndexingToken=&backgroundColor="
header = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}
res = requests.get(url, headers=header)
res.raise_for_status()
soup = BeautifulSoup(res.text, "lxml")

 

# beautifulsoup 4

- res = requests.get(url); res.raise_for_status() 는 항상 같이 적어준다

 

- soup = BeautifulSoup(res.text, "lxml") 

lxml 파서로 res.text 텍스트를 객체로 생성하는 작업

 

- soup.a
  soup 객체에서 처음 나타나는 태그의 내용 출력

 

- soup.title

  title내용 출력

 

- soup.a.attrs

  a의 속성정보 출력

 

- soup.a["href"]

  맨처음 a태그의 링크태그 href의 내용

 

- soup.find("a", attrs = {"class" : "클래스이름"})

  해당 클래스이름 중 a태그인 것을 찾아서 출력

 

- soup.find(attrs={"class" : "Nbtn_upload"})

  클래스 이름이 Nbtn_upload인 어떤 태그를 찾아줘 (태그명을 꼭 입력하지 않아도 됨)

 

- next_sibling.next_sibling

  객체의 다음 태그 내용을 출력

 

- previous_sibling(태그)   # 태그를 넣지 않아도 됨

  객체의 이전 태그 내용을 출력

import requests
from bs4 import BeautifulSoup

url = "https://comic.naver.com/index"
res = requests.get(url)
res.raise_for_status()

# html문서값을 lxml파서를 통해 soup객체를 만드는 작업
soup = BeautifulSoup(res.text, "lxml") 
# print(soup.title)  # <title>네이버 만화</title>
# print(soup.title.get_text())  # 네이버 만화 (태그가 제거됨)

# print(soup.a)  # soup 객체에서 처음 나타나는 a태그의 내용
# print(soup.a.attrs)  # a element의 속성 정보를 출력

# print(soup.a["href"]) # a원소의 href 속성값  --> #menu 출력

## <a href="/mypage/myActivity" class="Nbtn_upload" onclick="nclk_v2(event,'olk.upload');">웹툰 올리기</a>
# 위아 같은 태그에 대한 내용을 출력하고 싶을때 find함수 이용
tmp = soup.find("a", attrs={"class":"Nbtn_upload"})  # 클래스 이름이 Nbtn-이고 a태그인 것을 찾아줘
tmp = soup.find(attrs={"class":"Nbtn_upload"})  # class이름이 nbtn인 어떠한 태그를 찾아줘


# 실시간 웹툰 1등인 것을 출력해보기
# tmp = soup.find("li", attrs={"class":"rank01"})
# print(tmp.a)  # rank01클래스의 a태그 내용 출력


# 실시간 웹툰 1등, 2등, 3등 .. 차례로 정보 추출
rank1 = soup.find("li", attrs={"class":"rank01"})
print(rank1.a.get_text())  # 태그 제외 하고 출력됨 (외모지상주의-368화 원나잇lll [09])

rank2 = rank1.next_sibling.next_sibling
rank3 = rank2.next_sibling.next_sibling 

print(rank2.a.get_text()) # 나 혼자 만렙 뉴비-19화. 
print(rank3.a.get_text()) # 검성 천유성 재혼 황후-90화

rank2 = rank3.previous_sibling.previous_sibling
print(rank2.a.get_text()) # next 반대 명령어는 previous

# print(rank1.parent)
print()
tmp = rank1.find_next_sibling("li") # li 리스트 태그에 해당하는 것들만 출력
print(tmp.a.get_text())

print("-----------------------")
print(rank1.find_next_siblings("li"))

- 반복문 이용해서 출력

import requests
from bs4 import BeautifulSoup

url = "https://comic.naver.com/webtoon/weekday"
res = requests.get(url)
res.raise_for_status()

soup = BeautifulSoup(res.text, "lxml") 

# 만화 목록 모두 가져오기
cartoons = soup.find_all("a", attrs={"class":"title"}) # 태그명이 a이고 클래스가 title인 모든 값들

for cartoon in cartoons:
    print(cartoon.get_text())

 

- 만화 제목과 링크가 같이 출력

import requests
from bs4 import BeautifulSoup

url = 'https://comic.naver.com/webtoon/list?titleId=335885'
res = requests.get(url)
res.raise_for_status()

soup = BeautifulSoup(res.text, "lxml")

# 1) 가우스 웹툰 제목 출력
cartoons = soup.find_all("td",attrs={"class":"title"})
# title=cartoons[0].a.get_text()
# link = cartoons[0].a["href"] # 링크태그인 href의 내용을 가져온다
# print(title)
# print("https://comic.naver.com" + link)


# 2) 가우스 제목과 해당 만화 링크 같이 출력
for cartoon in cartoons:
    title = cartoon.a.get_text()
    link = "https://comic.naver.com" + cartoon.a["href"]
    print(title, link)

 

- 만화의 평점 가져오기

-- 만화 평점은 rating_type클래스의 div태그에 종속되어 있고

strong태그로 감싸져 있다.

# 3) 평점 구하기
total_ranks = 0
cartoons = soup.find_all("div",attrs={"class":"rating_type"})
for cartoon in cartoons:
    rank = cartoon.strong.get_text()
    print(rank)
    total_ranks += float(rank)

print("전체 평점은 ", total_ranks)
print("평균 점수는 ", total_ranks/len(cartoons))

## HTTP method

 

# get - 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

? 뒤는 변수와 값

& 변수와 값들을 구분

 

# post - url이 아닌 http바디에 숨겨서 보내는 방식

 개인정보같은 변수들을 숨겨서 보내는 전송 방식

 


# selenium

- 크롬 버전 확인 chrome://version/

- 크롬 버전에 맞는 web driver를 설치해줘야 한다.

# webdriver

- browser = webdriver.Chrome()

- broswer.get("http://naver.com")

- elem = brower.find_element_by_class_name("link_login")

- elem.click()

- browser.back()

- brower.forward()