1.在用python抓取图片的时候,很慢,因为是国外的网站,所以考虑使用分布式多进程的方式来提高抓取效率。

2.废话不多说,直接上demo,这个是核心的抓取图片类,wpd.py

# -*- coding:utf-8 -*-
import urllib
import urllib2
import re
import thread
import timeimport loggingclass Wpd:# 初始化方法,定义一些变量def __init__(self):# 定义一个Handler打印INFO及以上级别的日志到sys.stderrconsole = logging.StreamHandler()# 设置日志打印格式formatter = logging.Formatter('%(asctime)s-[%(name)s]-[%(funcName)s] - %(levelname)s - %(message)s')console.setFormatter(formatter)# 将定义好的console日志handler添加到root loggself.wpdlogger = logging.getLogger('wpd application')self.wpdlogger.setLevel(logging.INFO)self.wpdlogger.addHandler(console)self.pageIndex = 2self.hasReadPage = 0self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'# 初始化headersself.headers = {'User-Agent': self.user_agent}# 存放段子的变量,每一个元素是每一页的段子们self.stories = []# 存放程序是否继续运行的变量self.enable = False# 传入某一页的索引获得页面代码def getPage(self, pageIndex):try:url = 'http://www.2wpd.com/advanced-search?q=&category=2&resolution=&license=&page=' + str(pageIndex)# 构建请求的requestrequest = urllib2.Request(url, headers=self.headers)# 利用urlopen获取页面代码response = urllib2.urlopen(request)# 将页面转化为UTF-8编码pageCode = response.read().decode('utf-8')return pageCodeexcept urllib2.URLError, e:if hasattr(e, "reason"):self.wpdlogger.error(u"连接原服务器失败,错误原因"+e.reason)self.wpdlogger.error(url)return Nonedef getdetailPage(self, prefix):try:url = 'http://www.2wpd.com/landscape/'+prefix+'.htm'# 构建请求的requestrequest = urllib2.Request(url, headers=self.headers)# 利用urlopen获取页面代码response = urllib2.urlopen(request)# 将页面转化为UTF-8编码pageCode = response.read().decode('utf-8')return pageCodeexcept urllib2.URLError, e:if hasattr(e, "reason"):self.wpdlogger.error(u"连接原服务器失败,错误原因"+e.reason)self.wpdlogger.error(url)return None# 获取图片并存入def getImg(self, html):flag =Falseprefix = html.lower();pageinfo = self.getdetailPage(prefix)if not pageinfo:return None# pattern = re.compile('<div.*?author">.*?<a.*?<img.*?>(.*?)</a>.*?<div.*?'+#                  'content">(.*?)<!--(.*?)-->.*?</div>(.*?)<div class="stats.*?class="number">(.*?)</i>',re.S)pattern = re.compile('<a href="/preview/(.*?).htm".*?</a>',re.S)items = re.findall(pattern, pageinfo)for item in items:#仅爬取1280*800图片if re.search('1280x800',item):if len(items)>0:imagesrc = 'http://www.2wpd.com/images/%s.jpg' % itemflag = self.download(imagesrc,prefix)breakreturn flagdef download(self,imagesrc,prefix):return urllib.urlretrieve(imagesrc, 'D:\wpd\%s.jpg' % prefix)# 传入某一页代码def getPageItems(self,pageindex):pi =self.hasReadPage+1for pagenumber in range(pi,pageindex):self.hasReadPage=pipageCode = self.getPage(pagenumber)pageStories = []if not pageCode:self.wpdlogger.error(u"页面加载失败,错误原因")return Nonepattern = re.compile('<img itemprop=".*?src="/uploads/wallpapers/.*?/.*?/.*?/(.*?)/.*?alt="(.*?)" .*?>',re.S)items = re.findall(pattern, pageCode)# 用来存储每页图片altpageAlt = []# 遍历正则表达式匹配的信息for item in items:# 是否含有图片# haveImg = re.search("img",item[3])# #如果不含有图片,把它加入list中text = re.sub("\s+", "-", item[1])text = re.sub("-Wallpaper", "", text)text = text + '-' + item[0]# self.getImg(text)pageStories.append(text);# replaceBR = re.compile('<br/>')return pageStories# 开始方法def start(self):return self.getPageItems()

2.抓取的图片服务端,taskmanager.py,这里创建了两个队列,一个发送下载任务的队列、另一个接受下载结果的队列。

# -*- coding:utf-8 -*-#################分布式爬虫demo,manager###########################
from spider import wpd
import threading
import random, time, Queue,logging
import dill
from multiprocessing.managers import BaseManager# 定义一个Handler打印INFO及以上级别的日志到sys.stderr
console = logging.StreamHandler()
# 设置日志打印格式
formatter = logging.Formatter('%(asctime)s -[%(threadName)s] - %(levelname)s - %(message)s')
console.setFormatter(formatter)
# 将定义好的console日志handler添加到root logg
logger = logging.getLogger('manager')
logger.setLevel(logging.INFO)
logger.addHandler(console)# 从BaseManager继承的QueueManager:
class QueueManager(BaseManager):pass
def make_server_manager():# 发送任务的队列:task_queue = Queue.Queue()# 接收结果的队列:result_queue = Queue.Queue()# 把两个Queue都注册到网络上, callable参数关联了Queue对象:QueueManager.register('get_task_queue', callable=lambda: task_queue)QueueManager.register('get_result_queue', callable=lambda: result_queue)# 绑定端口5000, 设置验证码'abc':manager = QueueManager(address=('127.0.0.1', 5000), authkey='abc')# 启动Queue:manager.start()t1 = threading.Thread(target=startTask, name='TaskQueue',args=(manager,))t2 = threading.Thread(target=startresultQueue, name='ResultQueue',args=(manager,))t1.start()t2.start()# t1.join()# t2.join()def startTask(manager):# 初始化爬虫spider1 = wpd.Wpd()# 获得通过网络访问的Queue对象:task = manager.get_task_queue()# 爬取页数:page =10n=1while page>=n:logger.info(u'读取第 %d页....' % n)n += 1imgs = spider1.getPageItems(n)for v in imgs:# n = random.randint(0, 10000)logger.info(u'下载任务放入队列 %s...' % v)task.put(v)
# 从result队列读取结果:
def startresultQueue(manager):result = manager.get_result_queue()logger.info(u'尝试获取下次结果...')while True:try:r = result.get(timeout=10)logger.info(u'结果: %s' % r)except Queue.Empty:logger.warning('task queue is empty.')# 关闭:manager.shutdown()if __name__=='__main__':make_server_manager()

3.启动多个worker下载图片,并把下载结果返回给服务端

# -*- coding:utf-8 -*-
#################分布式爬虫demo,worker###########################3
import time, sys, Queue
from multiprocessing.managers import BaseManager
from multiprocessing import Process
import loggingfrom spider import wpd# 创建类似的QueueManager:
class QueueManager(BaseManager):passdef start_client():# 定义一个Handler打印INFO及以上级别的日志到sys.stderrconsole = logging.StreamHandler()# 设置日志打印格式formatter = logging.Formatter('%(asctime)s -[%(name)s] - %(levelname)s - %(message)s')console.setFormatter(formatter)# 将定义好的console日志handler添加到root logglogger = logging.getLogger('client')logger.setLevel(logging.INFO)logger.addHandler(console)# 由于这个QueueManager只从网络上获取Queue,所以注册时只提供名字:QueueManager.register('get_task_queue')QueueManager.register('get_result_queue')# 连接到服务器,也就是运行taskmanager.py的机器:server_addr = '127.0.0.1'logger.info('Connect to server %s...' % server_addr)# 端口和验证码注意保持与taskmanager.py设置的完全一致:m = QueueManager(address=(server_addr, 5000), authkey='abc')# 从网络连接:m.connect()# 获取Queue的对象:task = m.get_task_queue()result = m.get_result_queue()spider1 = wpd.Wpd()# 从task队列取任务,并把结果写入result队列:while True:try:n = task.get()logger.info(u'开始下载图片 %s...' % n)flag = spider1.getImg(n)#result.put('cuck')r = u'图片 '+ n +u' 下载 失败'if flag:r = u'图片 ' + n + u' 下载 成功'logger.info(u'下载图片完成 %s.............finish' % n)result.put(r)except Queue.Empty:logger.info('task queue is empty.')if __name__ == '__main__':#启动10个进程做这个事情for n in range(10):p1 = Process(target=start_client)p1.start()

4,分别启动worker和mananger,获取结果

客户端运行截图

服务器端运行截图

转载于:https://my.oschina.net/u/2402325/blog/868440

python 多进程爬虫相关推荐

  1. 以爬取知乎为例,进行python 多进程爬虫性能分析

    以爬取知乎为例,进行python 多进程爬虫性能分析 如果对多进程multiproessing模块不熟悉,请先浏览 python 使用multiprocessing模块进行多进程爬虫 问题背景: 爬取 ...

  2. python多进程爬虫保存数据_Python多进程爬虫东方财富盘口异动数据+Python读写Mysql与Pandas读写Mysql效率对比...

    先上个图看下网页版数据.mysql结构化数据 通过Python读写mysql执行时间为:1477s,而通过Pandas读写mysql执行时间为:47s,方法2速度几乎是方法1的30倍.在于IO读写上, ...

  3. python多进程爬虫解决进程挂掉问题

    这几天写了个爬虫,爬取的数据比较多.一直挂在服务器上跑,后面发现启动十个进程总会运行着某几个进程挂掉,导致数据采集工作比较延后. 后面重新改进了一下,从日志中读取当前进程断点,继续爬取. 用了一个笨方 ...

  4. python爬虫用多线程还是多进程_python爬虫之多线程、多进程爬虫

    多线程对爬虫的效率提高是非凡的,当我们使用python的多线程有几点是需要我们知道的: countdown是一个计数的方法,正常执行它,我们一般使用countdown(10),就可以达到执行的目的,当 ...

  5. python爬虫之多线程、多进程爬虫

    一.原因 多线程对爬虫的效率提高是非凡的,当我们使用python的多线程有几点是需要我们知道的: 1.Python的多线程并不如java的多线程,其差异在于当python解释器开始执行任务时,受制于G ...

  6. python异步爬虫_Python实战异步爬虫(协程)+分布式爬虫(多进程)

    转自:https://blog.csdn.net/SL_World/article/details/86633611 在讲解之前,我们先来通过一幅图看清多进程和协程的爬虫之间的原理及其区别.(图片来源 ...

  7. python+selenium多线程与多进程爬虫

    使用python+selenium抓取深圳证券交易所本所公告数据,刚开始是用单进程爬取的,最近将代码修改了一下,分别用多进程和多线程进行抓取,速度非常快.如果对selenium不了解的请移步别的地方学 ...

  8. 取代Python多进程!伯克利开源分布式框架Ray

    Ray由伯克利开源,是一个用于并行计算和分布式Python开发的开源项目.本文将介绍如何使用Ray轻松构建可从笔记本电脑扩展到大型集群的应用程序. 并行和分布式计算是现代应用程序的主要内容.我们需要利 ...

  9. python爬虫文件代码大全-Python网络爬虫实战项目代码大全(长期更新,欢迎补充)...

    WechatSogou[1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典.[1]: https://github ...

最新文章

  1. 根据PromiseA+规范实现Promise
  2. spire.doc 转html,c# html 转Word--Spire.Doc
  3. mysql支持UUID做外键_多表外键下将普通的id主键更新为uuid主键
  4. oracle limsize,Oracle9i AIX上单进程占用内存过多问题
  5. POJ1363Rails队列和栈应用
  6. QML Imports声明
  7. 带有Prometheus的Spring Boot和测微表第6部分:保护指标
  8. 使用 WebBrowser 操作 js
  9. SVC较好的介绍资料
  10. python 谷歌翻译 api_python免费调用谷歌翻译接口
  11. android opencv hu 不变矩,图像的矩(含hu不变矩)
  12. Caused by : java.lang.NoSuchMethodError
  13. KlipC数据显示2022年日元兑美元汇率有进一步下跌的风险和可能性
  14. 深信服AD应用交付管理维护
  15. 小乐乐与进制转换-c++(六进制转换函数)
  16. 计算机网络月考题职专一年级,职高一年级计算机专业WORD试题
  17. 市场营销学4——市场调研与预测
  18. 国产信息化自主创新行业简介
  19. 计算机组成原理概念学习DAY7——外围设备
  20. web3.0的基石BYDK,带来革命性的新玩法,腾飞在即

热门文章

  1. 【小波能量BP】基于小波能量系数提取和BP神经网络的检测算法matlab仿真
  2. 【若依(ruoyi)】附件上传功能
  3. 计算机技术对视力的影响,电子屏幕对视力有哪些影响
  4. PCB板材知识及标准
  5. 使您的软件运行起来: 了解有关缓冲区溢出方面的基础知识
  6. 企业实施5S管理经典推行步骤及注意事项(完整收藏版)
  7. LCD液晶屏模块工作响应时间和背光寿命?
  8. 一文弄懂软件发布生命周期中各阶段名称及代表含义
  9. MODIFY EXTENT SIZE 子句
  10. DNS服务器配置- windows2012