python爬虫学习:多线程抓取

                                                                                                                                  上文在有提到过?反爬虫?的问题,禁止访问只是?反爬虫?的其中一种策略,下面来讲另外一种反爬虫策略?抓取时间

                                                                                                                                  假设一个爬虫程序抓取网页的速度和正常用浏览器复制的速度一样,那么这个爬虫程序无疑是失败的,假设要抓取的信息很多,一个爬虫程序跑几天都没跑完,那么应该要想到提高程序的效率。例如一个新闻公司需要爬虫工程师去抓取实时的新闻资讯,这样就会对爬虫的速度有很大的要求,要保证?实时?,所以爬虫要抓取得快,而不是现在更新出新的新闻了,而你的程序还没抓完上个小时的新闻,因此本文要从提高爬虫的效率来写,主要介绍?2?个多线程的库:

                                                                                                                                  threading
                                                                                                                                  concurrent.futures
                                                                                                                                  

                                                                                                                                  在前文中作者抓取自己网页?首页?的图片,在程序中是以一个?for?来以此下载图片的,每张图片大约?100kb-200kb?,但是作者的带宽是能达到?1M/s?,假设能让这11张图片同时下载,那么将节约一部分时间出来,现在介绍这2个多线程库的用法。

                                                                                                                                  threading

                                                                                                                                  threading?是官方库,无需自己安装,直接就可以调用。本文将下载图片的代码封装成一个?function?,再将图片的?imgurl?传入到这个?function?里面,用?threading?执行?function?就会自动变成多线程了。

                                                                                                                                  调用的方式也很简单:

                                                                                                                                  import threading
                                                                                                                                  '''
                                                                                                                                  遇到python不懂的问题,可以加Python学习交流群:1004391443一起学习交流,群文件还有零基础入门的学习资料
                                                                                                                                  '''
                                                                                                                                  # 创建线程池
                                                                                                                                  threadpool = []
                                                                                                                                  # 定义线程
                                                                                                                                  th = threading.Thread(target=fun_name, args=(args))
                                                                                                                                  # 将线程加入线程池
                                                                                                                                  threadpool.append(th)
                                                                                                                                  # 开始线程
                                                                                                                                  for th in threadpool:
                                                                                                                                      th.start()
                                                                                                                                  # 等待所有线程运行完毕
                                                                                                                                  for th in threadpool:
                                                                                                                                      th.join()
                                                                                                                                  

                                                                                                                                  这里只要将下载图片的代码改写成函数?fun_name?,传入的参数为?img_src?就行。例如函数可以写成:

                                                                                                                                  def downloadimg(imgurl,imgname):
                                                                                                                                      saveimg = open("E:/" + str(imgname) + ".jpg", 'wb')
                                                                                                                                      saveimg.write(urllib.request.urlopen(imgurl).read())
                                                                                                                                      saveimg.close()
                                                                                                                                  

                                                                                                                                  最后根据前面学到的方法,将所有图片的?img_url?定义到线程里面去,即:

                                                                                                                                  for imgurl in imgurls:
                                                                                                                                      th = threading.Thread(target=downloadimg, args=(imgurl,imgname))
                                                                                                                                  	threadpool.append(th)
                                                                                                                                  

                                                                                                                                  最后开启线程,这样就可以让所有的图片,也就是?11?张图片一起下载:

                                                                                                                                  concurrent.futures

                                                                                                                                  concurrent.futures?其实也是基于?threading?封装的官方库,这个库更加简单粗暴,可以随意定义线程的数量,只要自己的机器承受得住,那么可以开随意多的线程来并发执行抓取任务,这也是爬虫必须了解的一个库。

                                                                                                                                  concurrent.futures?调用的方式也很简单:

                                                                                                                                  from concurrent.futures import ThreadPoolExecutor
                                                                                                                                  # 定义线程的最大数量为11,因为一共是11张图片
                                                                                                                                  pool=ThreadPoolExecutor(max_workers=11)
                                                                                                                                  # 将下载图片的任务加入线程
                                                                                                                                  for imgurl in imgurls:
                                                                                                                                      newimgurl = "http://www.tybai.com/" + imgurl[1].replace("\\", "")
                                                                                                                                      pool.submit(downloadimg,newimgurl,imgname)
                                                                                                                                  展开阅读全文

                                                                                                                                  没有更多推荐了,返回首页