在上一篇教程 从零开始的爬虫教程(1)——从urllib开始 中我简单地介绍了Python中使用urllib获取的方法,并介绍了根据已有链接列表批量获取网页的方法。但是在实际爬取TechPowerUp数据库的过程中,常常由于网络质量不佳,每次获取都需要大量的无效等待时间。在这篇教程中,我将会讲讲加速爬取的方法。注意,这篇文章不适用于Windows。我将会在不久后特别写一篇在Windows下加速爬取的方法。
寒假作业做完了怎么办?那当然是刷五(bī)三(zhān)啦。Python也一样。当他在等待一个请求的答复时,我们可以把这些多余的算力和带宽用在其他请求上。因此,我们需要一个十分强大的机制——多线程。
Python提供了一个简单易用的多线程方法os.fork()
,但是这个方法仅仅在Unix家族系统上可用。因此这篇文章仅仅适用于Unix家族系统,它包括Linux系统,BSD系列系统,macOS以及Android,它不适用于Windows。我们只需要在主程序开始之前执行如下代码:
os.fork()
主程序就自动分为两个了。但是仅有如此还不够,我们需要的并不是每个线程执行相同的程序,而是要它们分工协作爬取数据库。os.fork()
方法执行时会返回一个索引号,这个索引号在子线程是0,在父线程是子线程对应的PID。因此我们得到如下获取线程序号的代码:
pid = 0
for i in range(forks):
ret = os.fork()
if ret == 0:
break
pid += 1
if pid >= forks: exit()
print('Worker #' + str(pid) + ' is ready.')
其中forks是我们需要的线程数,pid是线程代号(注意这里不是Linux进程管理中的PID)。由此,我们可以得到完整的多线程爬取程序。输入python3 1.py
执行后结果如下图所示:
可以看到,程序同时放出了多个连接。这样子爬取速度简直就是成倍的提升啊。根据我自己的测试,在阿里云ECS上可以跑100-200个线程,在我自己的笔记本电脑上(Intel® Core™ i7-8750H 和 16G内存)上可以开到3000个线程。整个GPU_links.txt
文件里面只有千来条链接,如果网络没问题的话就可以在一分钟内完成了。
参考链接: