我创建了一个简单的python程序,它可以抓取我最喜欢的食谱网站,并从主站点返回各个食谱URL。虽然这是一个相对快速和简单的过程,但我已经尝试将其扩展到网站内的多个网页。当我这样做时,从整个站点刮掉所有配方URL大约需要45秒。我希望这个过程更快,所以我尝试在我的程序中实现线程。
我意识到这里有一些错误,因为每个线程一遍又一遍地返回整个URL线程而不是“分割”#39;工作。有没有人对如何更好地实现线程有任何建议?我在下面写了我的工作。使用Python 3。
from bs4 import BeautifulSoup
import urllib.request
from urllib.request import urlopen
from datetime import datetime
import threading
from datetime import datetime
startTime = datetime.now()
quote_page='http://thepioneerwoman.com/cooking_cat/all-pw-recipes/'
page = urllib.request.urlopen(quote_page)
soup = BeautifulSoup(page, 'html.parser')
all_recipe_links = []
#get all recipe links on current page
def get_recipe_links():
for link in soup.find_all('a', attrs={'post-card-permalink'}):
if link.has_attr('href'):
if 'cooking/' in link.attrs['href']:
all_recipe_links.append(link.attrs['href'])
print(datetime.now() - startTime)
return all_recipe_links
def worker():
"""thread worker function"""
print(get_recipe_links())
return
threads = []
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
答案 0 :(得分:1)
我能够通过让工作人员从单个列表中处理所有数据来分配工作,而不是让他们全部单独运行整个方法。以下是我更改的部分。不再需要方法get_recipe_links
,因为其任务已移至其他方法。
all_recipe_links = []
links_to_process = []
def worker():
"""thread worker function"""
while(len(links_to_process) > 0):
link = links_to_process.pop()
if link.has_attr('href'):
if 'cooking/' in link.attrs['href']:
all_recipe_links.append(link.attrs['href'])
threads = []
links_to_process = soup.find_all('a', attrs={'post-card-permalink'})
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
while len(links_to_process)>0:
continue
print(all_recipe_links)
我多次运行新方法,平均需要0.02秒才能运行它。