多进程爬虫介绍
Python的多线程爬虫只能运行在单核上,各个线程以并发的方法运行。由于GIL(全局解释器锁)的存在,多线程爬虫并不能充分地发挥多核CPU的资源。 作为提升Python网络爬虫速度的另一种方法,多进程爬虫则可以利用CPU的多核,进程数取决于计算机CPU的处理器个数。由于运行在不同的核上,各个进程的运行是并行的。在Python中,如果我们要用多进程,就要用到multiprocessing这个库。 使用multiprocessing库有两种方法,一种是使用Process + Queue的方法,另一种方法是使用Pool + Queue的方法。
使用multiprocessing的多进程爬虫
multiprocessing对于习惯使用threading多线程的用户非常友好,因为它的理念是像线程一样管理进程,和threading很像,而且对于多核CPU的利用率比threading高得多。 当进程数量大于CPU的内核数量时,等待运行的进程会等到其他进程运行完毕让出内核为止。因此,如果CPU是单核,就无法进行多进程并行。 我们可以通过下面的函数了解我们电脑CPU的核心数量:
from multiprocessing
import cpu_count
print(cpu_count
())
结果是8,说明我的电脑是8核。
爬虫代码:
from multiprocessing
import Process
, Queue
import time
import requests
link_list
= []
with open('alexa.txt', 'r') as file:
file_list
= file.readlines
()
for eachone
in file_list
:
link
= eachone
.split
('\t')[1]
link
= link
.replace
('\n','')
link_list
.append
(link
)
start
= time
.time
()
class MyProcess(Process
):
def __init__(self
, q
):
Process
.__init__
(self
)
self
.q
= q
def run(self
):
print("Starting ", self
.pid
)
while not self
.q
.empty
():
crawler
(self
.q
)
print("Exiting ", self
.pid
)
def crawler(q
):
url
= q
.get
(timeout
=2)
try:
r
= requests
.get
(url
, timeout
=5)
print(q
.qsize
(),r
.status_code
, url
)
except Exception
as e
:
print(q
.qsize
(), url
, 'Error: ', e
)
if __name__
== '__main__':
workQueue
= Queue
(1000)
for url
in link_list
:
workQueue
.put
(url
)
for i
in range(0, 8):
p
= MyProcess
(workQueue
)
p
.daemon
= True`
p
.run
()
p
.join
()
end
= time
.time
()
print('Process + Queue多进程爬虫的总时间为:', end
-start
)
print('Main process Ended!')
结果:
在上述代码中,我们在多进程中设置了daemon,p.daemon = True,在多进程中,每个进程都可以单独设置它的属性,如果将daemon设置为True,当父进程结束后,子进程就会自动被终止。