python多线程与其他语言相比有很大的区别,python
中的多线程,由于cil锁
的缘故,导致cpu
同一时间只能执行一个线程,这样产生的问题就是别管你的cpu
是几核的,都没什么卵用。但是这种情况是计算密集性才会有的问题,如果牵涉到的是计算密集性,那么python
可以通过多线程来做这种操作,这样就解决了多核缺并不能提高效率的问题。
今天要用的爬虫其实是cpu
把任务分配给了其他硬件进行操作,cpu
只牵涉到了分配,其他不用自己处理,这样即使是多线程,轮询分配下任务并不降低什么效率,同样类型的IO操作
,我们都可以使用多线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import requests from bs4 import BeautifulSoup from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor import time all_urls = [] def get_url_list(target_url): list_infos = [] ret = requests.get(url=target_url) soup = BeautifulSoup(ret.text, 'html.parser') list_box = soup.find('div', attrs={ 'class':'list' }) lis = list_box.find_all('li') for li in lis: info = li.find('h3') title = info.find('a').text target = info.find('a').get('href') list_infos.append({ 'title' : title, 'target' : target }) return list_infos def run():
for item in range(1, 51): all_urls.append(get_url_list('http://www.chinamedevice.cn/product/12/11/1127/%s.html'%item))
def get_result(future): all_urls.append(future.result()) def thred_run(): with ThreadPoolExecutor(5) as pool: for item in range(1, 51): res = pool.submit(get_url_list, 'http://www.chinamedevice.cn/product/12/11/1127/%s.html' % item) res.add_done_callback(get_result)
if __name__ == '__main__': start = time.perf_counter() thred_run() end = time.perf_counter() print(all_urls, len(all_urls), '总用时:%s' % (end - start))
|
单次测试,使用常规的单进程单线程爬取50页即1500条数据所耗费的时间大约在45秒左右;而我们使用单进程5线程获取同样的数据大概耗费了10秒左右,具体线程数根据自己需求