Featured image of post 从零开始的爬虫教程(2)——加速!加速!加速!

从零开始的爬虫教程(2)——加速!加速!加速!

在上一篇教程 从零开始的爬虫教程(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执行后结果如下图所示:

1.png

可以看到,程序同时放出了多个连接。这样子爬取速度简直就是成倍的提升啊。根据我自己的测试,在阿里云ECS上可以跑100-200个线程,在我自己的笔记本电脑上(Intel® Core™ i7-8750H 和 16G内存)上可以开到3000个线程。整个GPU_links.txt文件里面只有千来条链接,如果网络没问题的话就可以在一分钟内完成了。

参考链接:

  1. https://docs.python.org/3/library/os.html
  2. https://docs.python.org/3/library/urllib.html
  3. https://www.techpowerup.com
  4. https://en.wikipedia.org/wiki/List_of_Linux_distributions
Built with Hugo
主题 StackJimmy 设计