python/크롤링

네이버 영화리뷰 크롤링 bs4

1.5볼트 2023. 3. 30. 20:26
728x90

전에 한 네이버 평점 크롤링과 비슷하다 다른 건 그때는 간단한 한마디? 와 평점이 리스트로 여러 개 있었지만

이건 그 평점에 대한 자세한 리뷰가 있다 한 페이지에 15개의 목록이 있으니까 이건 15배 정도 url을 가져와야 한다

당연히 시간도 더 많이 걸리고 그래서 빠르게 해결하기 위해 multiprocessing을 사용한다

한 번에 하나의 url 요청을 하고 요청이 올 때까지 기다리다 완료되면 다음 걸 하는 게 아니라 하나 요청하고 기다릴 동한 다음 걸 요청하고 이런 식으로 동작해서 훨씬 빠르다

사용법은 대충 객체 하나 만들고 프로세스 몇 개 쓸지 정해주고 그냥 map 함수로 실행시킬 함수에 변수를 대입하면 된다

multiprocessing 을 사용하지 않았을 때보다 10배 이상은 빠른 듯

 

참고로 이전 글과 이거 너무 많이 사용하면 ip 차단당할 수도 있으니까 적당히 해야 한다 빠르게 하면 더더욱

import requests
from bs4 import BeautifulSoup
import sqlite3
import time
import datetime
from multiprocessing import Pool, Manager


def ff(j):
	# db접속
    conn=sqlite3.connect("ex44.db")
    cur=conn.cursor()
    # 100번마다 시간출력
    if j%100==0:
        print(j,datetime.datetime.now())
    try:
    	# 주소 가져오기 html변환
        b=BeautifulSoup(requests.get(f"https://movie.naver.com/movie/board/review/list.naver?&page={j}").text,"html.parser")
        y=[]
        for i in b.select("tbody tr"):
        	# 원하는정보 태그로 찾기  
            a=i.find_all("td")
            mov=a[0].text.strip()
            title=a[1].text.strip()
            ty=a[2].text.replace("\n","").replace("\t","").replace("\r","").split("*")
            name=ty[0]
            day=ty[-1]
            point=int(a[3].find(class_="mask").get("style").split(":")[1][:-1])
            good=int(a[4].text.strip())
            see=int(a[5].text.strip())
            y.append([mov,title,name,day,point,good,see])
        #print(y)
        # 데이터베이스 업데이트
        cur.executemany("insert into mo3 values(?,?,?,?,?,?,?)",y)
        conn.commit()
    except Exception as e:
        print(e,j)
        
        
if __name__=="__main__":
  	
    global y
    manager = Manager()
    y = manager.list()
    j=int(input())
    pool = Pool(processes=32) #32개의 프로세스 사용 적당히 안쓰면 cpu사용 100퍼 찍음
    pool.map(ff,range(j,135000)) # 원하는 함수의 인풋값 내장함수인 map와 사용법 같음
    pool.close()
    pool.join()
    print(y)