Python爬虫之多线程下载豆瓣Top250电影图片

发表于:2018-6-20 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:刘欣    来源:51testing软件测试网采编

  爬虫项目介绍
  本次爬虫项目将爬取豆瓣Top250电影的图片,其网址为:https://movie.douban.com/top250, 具体页面如下图所示:
  本次爬虫项目将分别不使用多线程和使用多线程来完成,通过两者的对比,显示出多线程在爬虫项目中的巨大优势。本文所使用的多线程用到了concurrent.futures模块,该模块是Python中最广为使用的并发库,它可以非常方便地将任务并行化。在concurrent.futures模块中,共有两种并发模块,分别如下:
  多线程模式:ThreadPoolExecutor,适合 IO密集型任务;
  多进程模式:ProcessPoolExecutor,适合计算密集型任务。
  具体的关于该模块的介绍可以参考其官方网址:https://docs.python.org/3/library/concurrent.futures.html 。
  本次爬虫项目将会用到concurrent.futures模块中的ThreadPoolExecutor类,多线程下载豆瓣Top250电影图片。下面将会给出本次爬虫项目分别不使用多线程和使用多线程的对比,以此来展示多线程在爬虫中的巨大优势。
  不使用多线程
  首先,我们不使用多线程来下载豆瓣Top250电影图片,其完整的Python代码如下:
  import time
  import requests
  import urllib.request
  from bs4 import BeautifulSoup
  # 该函数用于下载图片
  # 传入函数: 网页的网址url
  def download_picture(url):
      # 获取网页的源代码
      r = requests.get(url)
      # 利用BeautifulSoup将获取到的文本解析成HTML
      soup = BeautifulSoup(r.text, "lxml")
      # 获取网页中的电影图片
      content = soup.find('div', class_='article')
      images = content.find_all('img')
      # 获取电影图片的名称和下载地址
      picture_name_list = [image['alt'] for image in images]
      picture_link_list = [image['src'] for image in images]
      # 利用urllib.request..urlretrieve正式下载图片
      for picture_name, picture_link in zip(picture_name_list, picture_link_list):
          urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name)
  def main():
      # 全部10个网页
      start_urls = ["https://movie.douban.com/top250"]
      for i in range(1, 10):
          start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i))
      # 统计该爬虫的消耗时间
      t1 = time.time()
      print('*' * 50)
      for url in start_urls:
          download_picture(url)
      t2 = time.time()
      print('不使用多线程,总共耗时:%s'%(t2-t1))
      print('*' * 50)
  main()
  其输出结果如下:
  **************************************************
  不使用多线程,总共耗时:79.93260931968689
  **************************************************
  去E盘中的douban文件夹查看,如下图:
  我们可以看到,在不使用多线程的情况下,这个爬虫总共耗时约80s,完成了豆瓣Top250电影图片的下载。
  使用多线程
  接下来,我们使用多线程来下载豆瓣Top250电影图片,其完整的Python代码如下:
  import time
  import requests
  import urllib.request
  from bs4 import BeautifulSoup
  from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
  # 该函数用于下载图片
  # 传入函数: 网页的网址url
  def download_picture(url):
      # 获取网页的源代码
      r = requests.get(url)
      # 利用BeautifulSoup将获取到的文本解析成HTML
      soup = BeautifulSoup(r.text, "lxml")
      # 获取网页中的电影图片
      content = soup.find('div', class_='article')
      images = content.find_all('img')
      # 获取电影图片的名称和下载地址
      picture_name_list = [image['alt'] for image in images]
      picture_link_list = [image['src'] for image in images]
      # 利用urllib.request..urlretrieve正式下载图片
      for picture_name, picture_link in zip(picture_name_list, picture_link_list):
          urllib.request.urlretrieve(picture_link, 'E://douban/%s.jpg' % picture_name)
  def main():
      # 全部10个网页
      start_urls = ["https://movie.douban.com/top250"]
      for i in range(1, 10):
          start_urls.append("https://movie.douban.com/top250?start=%d&filter=" % (25 * i))
      # 统计该爬虫的消耗时间
      print('*' * 50)
      t3 = time.time()
      # 利用并发下载电影图片
      executor = ThreadPoolExecutor(max_workers=10)  # 可以自己调整max_workers,即线程的个数
      # submit()的参数: 第一个为函数, 之后为该函数的传入参数,允许有多个
      future_tasks = [executor.submit(download_picture, url) for url in start_urls]
      # 等待所有的线程完成,才进入后续的执行
      wait(future_tasks, return_when=ALL_COMPLETED)
      t4 = time.time()
      print('使用多线程,总共耗时:%s' % (t4 - t3))
      print('*' * 50)
  main()
  其输出结果如下:
  **************************************************
  使用多线程,总共耗时:9.361606121063232
  **************************************************
  再去E盘中的douban文件夹查看,发现同样也下载了250张电影图片。
  总结
  通过上述两个爬虫程序的对比,我们不难发现,同样是下载豆瓣Top250电影,10个网页中的图片,在没有使用多线程的情况下,总共耗时约80s,而在使用多线程(10个线程)的情况下,总共耗时约9.5秒,效率整整提高了约8倍。这样的效率提升在爬虫中无疑是令人兴奋的。
  希望读者在看了本篇博客后,也能尝试着在自己的爬虫中使用多线程,说不定会有意外的惊喜哦~~因为,大名鼎鼎的Python爬虫框架Scrapy,也是使用多线程来提升爬虫速度的哦!



上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号