ThreadPoolExecutor
대 Thread
클래스의 성능에 관한 질문이 있는데, 그것은 나 자신에게 몇 가지 근본적인 이해가 부족한 것처럼 보입니다.ThreadPoolExecutor 대 threading.Thread
저는 두 가지 기능으로 웹 조각 모음을했습니다. 구문 분석 링크 해제 이미지를로드하기 위해 웹 사이트 홈페이지와 두 번째의 각 이미지에 대한 링크를 구문 분석 할 수 첫째 :
다음 코드 두 건으로에서 분할import threading
import urllib.request
from bs4 import BeautifulSoup as bs
import os
from concurrent.futures import ThreadPoolExecutor
path = r'C:\Users\MyDocuments\Pythom\Networking\bbc_images_scraper_test'
url = 'https://www.bbc.co.uk'
# Function to parse link anchors for images
def img_links_parser(url, links_list):
res = urllib.request.urlopen(url)
soup = bs(res,'lxml')
content = soup.findAll('div',{'class':'top-story__image'})
for i in content:
try:
link = i.attrs['style']
# Pulling the anchor from parentheses
link = link[link.find('(')+1 : link.find(')')]
# Putting the anchor in the list of links
links_list.append(link)
except:
# links might be under 'data-lazy' attribute w/o paranthesis
links_list.append(i.attrs['data-lazy'])
# Function to load images from links
def img_loader(base_url, links_list, path_location):
for link in links_list:
try:
# Pulling last element off the link which is name.jpg
file_name = link.split('/')[-1]
# Following the link and saving content in a given direcotory
urllib.request.urlretrieve(urllib.parse.urljoin(base_url, link),
os.path.join(path_location, file_name))
except:
print('Error on {}'.format(urllib.parse.urljoin(base_url, link)))
:
사례 1 : I
threads = []
t1 = threading.Thread(target = img_loader, args = (url, links[:10], path))
t2 = threading.Thread(target = img_loader, args = (url, links[10:20], path))
t3 = threading.Thread(target = img_loader, args = (url, links[20:30], path))
t4 = threading.Thread(target = img_loader, args = (url, links[30:40], path))
t5 = threading.Thread(target = img_loader, args = (url, links[40:50], path))
t6 = threading.Thread(target = img_loader, args = (url, links[50:], path))
threads.extend([t1,t2,t3,t4,t5,t6])
for t in threads:
t.start()
for t in threads:
t.join()
위 코드는 내 컴퓨터에서 10 초 동안 작업을 수행합니다.
사례 2 : 저는 18 초 ThreadPoolExecutor
with ThreadPoolExecutor(50) as exec:
results = exec.submit(img_loader, url, links, path)
위 코드의 결과를 사용하고 있습니다.
제 생각에 ThreadPoolExecutor
은 각 작업자를위한 스레드를 만듭니다. 그래서 max_workers
을 50으로 설정하면 50 개의 스레드가 발생하므로 작업을 더 빨리 완료해야합니다.
누군가 내가 여기에없는 것을 설명해 주시겠습니까? 나는 여기서 어리석은 실수를 범하고 있음을 인정하지만 나는 그것을 얻지 못한다.
감사합니다.
에서 단지 : 대신
당신이 필요 했어. 그래서 나는 단지 하나의 링크를 받아들이도록 내'img_loader' 함수를 변경 한 다음 컨텍스트 관리자 아래에'for' 루프를 추가하여 목록의 각 링크를 처리했습니다. 그리고 그것은 3.8s로 시간을 감소 시켰습니다. – Vlad