分布式爬虫样例1
2015-10-14 09:59
543 查看
Python、Redis实现分布式网络爬虫
http://www.bubuko.com/infodetail-820679.html
写爬虫关键是思路,思路明确代码实现起来不是问题。
关于用Python实现一个分布式爬虫,我曾折腾了很长一段时间,翻遍了Google十几页,和
Python分布式爬虫等关键字相关的博客也就那么几篇,后来在学习Redis的时候,终于找到了实现分布式的方法。看来当现有的技术解决不了实际问题的时候,是需要学习新的技术了。
具体实现思路:利用Redis的主从数据同步,所有爬虫获取到的url都放到一个redisqueue中,并且Master和Slave的爬虫都从这个redisqueue中获取url。
需要用到的工具redis-py。
我有两台机器,笔记本Windows,树莓派Linux,笔记本做Master,树莓派做Slave。
爬取网站http://jandan.net/(经常写爬虫的应该不会不知道这个网站。)
以前写爬虫的时候我会把需要下载的URL放在Queue里面,而现在需要把URL放在redisqueue中,借鉴了网上一篇博客的代码
这段代码作为一个模块的形式,文件命名为RedisQueue.py,和爬虫文件放在同一个文件夹里面,具体操作和Queue差不多
先用一段代码将URL放进redisqueue中
然后在Master端可以看到:
Slave端:
现在Master和Slave都可以读取redisqueue中的数据,下面的工作就是Master和Slave分别运行自己的爬虫对redisqueue中的数据下载就行了。
Windows爬虫代码
Linux爬虫代码:
将这两段代码同时运行,即可对redisqueue中的URL同时下载,直到把redisqueue取空为止。
写爬虫关键是思路,思路明确代码实现起来不是问题。
关于用Python实现一个
Python分布式
具体实现思路:利用Redis的主从数据同步,所有爬虫获取到的url都放到一个redisqueue中,并且Master和Slave的爬虫都从这个redisqueue中获取url。
需要用到的工具redis-py。
我有两台机器,
爬取网站
以前写爬虫的时候我会把需要下载的URL放在Queue里面,而现在需要把URL放在redisqueue中,借鉴了网上一篇博客的代码
importredis
classRedisQueue(object):
"""SimpleQueuewithRedisBackend"""
def__init__(self,name,namespace=‘queue‘,**redis_kwargs):
"""Thedefaultconnectionparametersare:host=‘localhost‘,port=6379,db=0"""
self.__db=redis.Redis(host=‘192.168.1.105‘,port=6379,db=0)
self.key=‘%s:%s‘%(namespace,name)
defqsize(self):
"""Returntheapproximatesizeofthequeue."""
returnself.__db.llen(self.key)
defempty(self):
"""ReturnTrueifthequeueisempty,Falseotherwise."""
returnself.qsize()==0
defput(self,item):
"""Putitemintothequeue."""
self.__db.rpush(self.key,item)
defget(self,block=True,timeout=None):
"""Removeandreturnanitemfromthequeue.
IfoptionalargsblockistrueandtimeoutisNone(thedefault),block
ifnecessaryuntilanitemisavailable."""
ifblock:
item=self.__db.blpop(self.key,timeout=timeout)
else:
item=self.__db.lpop(self.key)
ifitem:
item=item[1]
returnitem
defget_nowait(self):
"""Equivalenttoget(False)."""
returnself.get(False)
这段代码作为一个模块的形式,文件命名为RedisQueue.py,和
>>>fromRedisQueueimportRedisQueue
>>>q=RedisQueue(‘test‘)
>>>q.put(‘helloworld‘)
redis127.0.0.1:6379>keys*
1)"queue:test"
redis127.0.0.1:6379>typequeue:test
list
redis127.0.0.1:6379>llenqueue:test
(integer)1
redis127.0.0.1:6379>lrangequeue:test01
1)"helloworld"
>>>fromRedisQueueimportRedisQueue
>>>q=RedisQueue(‘test‘)
>>>q.get()
‘helloworld‘
先用一段代码将URL放进redisqueue中
#coding=utf-8
frombs4importBeautifulSoup
importurllib2
fromQueueimportQueue
fromRedisQueueimportRedisQueue
queue=Queue()
redis=RedisQueue(‘jandan3‘)
defuser_agent(url):
req_header={‘User-Agent‘:‘Mozilla/5.0(WindowsNT6.1;WOW64;rv:34.0)Gecko/20100101Firefox/34.0‘}
req_timeout=20
req=urllib2.Request(url,None,req_header)
page=urllib2.urlopen(req,None,req_timeout)
html=page
returnhtml
defnext_page():
base_url=‘http://jandan.net/ooxx/page-1006#comments‘
foriinrange(3):
html=user_agent(base_url).read()
soup=BeautifulSoup(html)
next_url=soup.find(‘a‘,{‘class‘:‘next-comment-page‘,‘title‘:‘NewerComments‘}).get(‘href‘)
yieldbase_url
base_url=next_url
forpageinnext_page():
queue.put(page)
print‘Thereare%dpages‘%queue.qsize()
whilenotqueue.empty():
page_url=queue.get()
html=user_agent(page_url).read()
soup=BeautifulSoup(html)
img_urls=soup.find_all([‘img‘])
formyimginimg_urls:
Jpgurl=myimg.get(‘src‘)
redis.put(Jpgurl)
print‘Thereare%dpictures‘%redis.qsize()
然后在Master端可以看到:
redis192.168.1.105:6379>keys*
1)"queue:jandan3"
redis192.168.1.105:6379>
Slave端:
192.168.1.106:6379>keys*
1)"queue:jandan3"
192.168.1.106:6379>
现在Master和Slave都可以读取redisqueue中的数据,下面的工作就是Master和Slave分别运行自己的爬虫对redisqueue中的数据下载就行了。
Windows爬虫代码
importurllib2
fromRedisQueueimportRedisQueue
redis=RedisQueue(‘jandan3‘)
defuser_agent(url):
req_header={‘User-Agent‘:‘Mozilla/5.0(WindowsNT6.1;WOW64;rv:34.0)Gecko/20100101Firefox/34.0‘}
req_timeout=20
req=urllib2.Request(url,None,req_header)
page=urllib2.urlopen(req,None,req_timeout)
html=page
returnhtml
whilenotredis.empty():
down_url=redis.get()
data=user_agent(down_url).read()
withopen(‘D:/Python/picture‘+‘/‘+down_url[-11:],‘wb‘)ascode:
code.write(data)
printdown_url
Linux
importurllib2
fromRedisQueueimportRedisQueue
redis=RedisQueue(‘jandan3‘)
defuser_agent(url):
req_header={‘User-Agent‘:‘Mozilla/5.0(WindowsNT6.1;WOW64;rv:34.0)Gecko/20100101Firefox/34.0
‘}
req_timeout=20
req=urllib2.Request(url,None,req_header)
page=urllib2.urlopen(req,None,req_timeout)
html=page
returnhtml
whilenotredis.empty():
down_url=redis.get()
data=user_agent(down_url).read()
withopen(‘/mz/picture‘+‘/‘+down_url[-11:],‘wb‘)ascode:
code.write(data)
printdown_url
将这两段代码同时运行,即可对redisqueue中的URL同时下载,直到把redisqueue取空为止。
相关文章推荐
- 三个annotation类型(RetentionPolicy,ElementType)
- .NET Framework 4.0安装时发生严重错误解决方法
- 使用Ant打包工具
- 使用Ant打包工具
- HOPE——懦怯囚禁人的灵魂,希望可以感受自由。强者自救,圣者渡人。
- 性能测试培训:分析内训泄露的案例
- webstorm使用技巧
- 好久不写博客了
- java中的printf的用法
- oracle索引介绍
- 什么是常识?
- Linux安装Git及详细使用
- IE8下按F12不显示开发人员工具窗口的解决方法
- 老李分享知识:性能测试之吞吐量
- Global.asa文件技巧用法
- 1437 迈克步
- css控制div左侧列表排列
- 使用commons-fileupload.jar servlet上传文件 遇到的问题
- jsonp 例子
- 正则表达式基本语法详解