基于广域网的主从分布式爬虫系统

2024-04-01 06:58

本文主要是介绍基于广域网的主从分布式爬虫系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


241133427088097


目的:构造基于广域网的主从分布式爬虫系统,以asp300网站为例,主机用来爬取任务地址,从机在每次任务完成会向主机发送任务请求,由主机分配任务。

原理:

整个爬虫系统分为两块,一块是主机,一块是从机,从机数量不限,视主机的瓶颈压力而定!主机一般只用一台,但如果性能不够或者达到性能瓶颈,那主机就成了限制整个爬虫系统的最大效率的瓶颈,这也就是所谓的“木桶效应”。

如何提高主机效率在本篇文章中不做研究,大家自行探索。


实现工具:

语言:Python

  网址:ASP300.COM

环境:腾讯云学生主机(配置:1GHZ   单核   1G内存)


代码示例:

主机代码:

#coding=gb2312
import urllib2
import urllib
import random
import socket
from bs4 import BeautifulSoup
user_agent = ["User-Agent,Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36","User-Agent,Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","User-Agent,Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","User-Agent,Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;","User-Agent,Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1","User-Agent,Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11","User-Agent, Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)"]def iteration():url_list = []for i in range(1, 100):url = 'http://www.asp300.com/SoftList/27/27_%d.html' % i# 伪造用户身份headers = {'User-Agent': user_agent[random.randint(0, 6)]}  # 随机headersreq = urllib2.Request(url=url, headers=headers)#测试页面是否能丢失try:response = urllib2.urlopen(req)except urllib2.URLError, e:if hasattr(e, 'code') and e.code == 404:continueurl_list.append(url)return url_listdef server(url_list):HOST = ''PORT = 21567BUFSIZ = 1024ADDR = (HOST,PORT)#创建套接字tcpSerSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)while True:#死循环,使主机保持接受从机访问print 'waiting for connection......'tcpCliSock, addr = tcpSerSock.accept()print '...connected from:',addrwhile True:data = tcpCliSock.recv(BUFSIZ)if not data:break#发送任务到从机tcpCliSock.send('%s'%url_list.pop)tcpCliSock.close()tcpSerSock.close()if __name__ == 'main':url_list = iteration()server(url_list)

 

从机代码:

#coding=gb2312
import urllib2
import urllib
import cookielib
import re
from PIL import Image
from bs4 import BeautifulSoup
import socket
import timeclass MyError(Exception):#定义一个错误,留引发passclass IgnoError(Exception):#定义一个错误,留引发passclass RedirctHandler(urllib2.HTTPRedirectHandler):#重构302,301页面处理类"""docstring for RedirctHandler"""def http_error_301(self, req, fp, code, msg, headers):if 'location' in headers:newurl = headers.getheaders('location')[0]elif 'uri' in headers:newurl = headers.getheaders('uri')[0]else:returnreturn newurldef http_error_302(self, req, fp, code, msg, headers):if 'location' in headers:newurl = headers.getheaders('location')[0]elif 'uri' in headers:newurl = headers.getheaders('uri')[0]else:returnreturn newurldef Download(url,headers,num_retries=9):#下载url所指向的页面req = urllib2.Request(url, headers=headers)try:response = urllib2.urlopen(req,timeout=60)the_page = response.read()response.close()except urllib2.URLError,e:if num_retries > 0 and hasattr(e,'code') and (500 <= e.code <600):return Download(url,headers,num_retries - 1)elif hasattr(e, 'code') and (e.code == 404):raise IgnoErrorelse:print 'Download Error:', e.reasonraise MyErrorexcept socket.timeout:if num_retries > 0 :return Download(url, headers, num_retries - 1)raise socket.timeoutreturn the_pagedef resolve(html):#提取源码信息image_url = []soup = BeautifulSoup(html,"lxml")title = unicode(soup.head.title.string)title = re.search('(.*?)_ASP300',title).groups()[0]size = soup.find('div',class_='box').find('div',class_='box_1').find('div',id='goodsInfo').find('div',class_='textInfo').ul.find_all('li')[2].ddsize = unicode(size)size = float(re.search(u'软件大小:(.*?)\D',size).groups()[0])summary_tag = soup.find('div',class_='s')summary_content = unicode(summary_tag).strip()summary_content = summary_content.split('<br/>')summary_content[0] = summary_content[0][15:]del summary_content[len(summary_content)-1]for a,b in enumerate(summary_content):if b == '\n':del summary_content[a]summary_cahe = u''for c in summary_content:summary_cahe += (c + u'<br/>')summary_content = summary_cahefor i in summary_tag.p.find_all('img'):image_url.append('http://www.asp300.com' + i['src'])#获取图片下载地址,放入image_url中,image_url中的元素为str,非unicodereturn title,size,summary_content,image_url#title,summary是unicode,size是float,image_url中的元素均为strdef download_image(name,url,headers,num_tries=9):#下载图片req = urllib2.Request(url=url,headers=headers)try:f = urllib2.urlopen(req,timeout=60)except urllib2.URLError, e:if num_tries > 0 and hasattr(e,'code') and 500 <= e.code <600:return download_image(name,url,headers,num_tries - 1)else:print '下载图片出错:',e.reasonraise MyErrorexcept socket.timeout:if num_tries > 0 :return download_image(name,url,headers,num_tries - 1)raise socket.timeoutimage = open(name,'wb')image.write(f.read())f.close()image.close()def screenshot(name,change,format):# 去除水印im = Image.open(name)w,h = im.sizebox = (0,0,w,h-change)region = im.crop(box)region.save(name,format)def soft_url(url,headers,num_retries=9):#获取软件真实下载地址id = int(re.search('SoftView_(.*?).html',url).groups()[0])url1 = 'http://www.asp300.com/2012dll/Down.jsp?CodeID=%d&id=1'%id#这一步是为了获取商品的ookiecookie = cookielib.CookieJar()handler = urllib2.HTTPCookieProcessor(cookie)opener1 = urllib2.build_opener(handler)req1 = urllib2.Request(url=url1,headers=headers)try:opener1.open(req1,timeout=60)print '%s:获取下载COOKIE成功'%time.ctime()except urllib2.URLError, e:if num_retries > 0 and hasattr(e,'code') and (500 <= e.code <600):return soft_url(url,headers,num_retries - 1)else:print 'SOFT_URL1 Error:', e.reasonraise MyErrorexcept socket.timeout:if num_retries > 0:return soft_url(url, headers, num_retries - 1)raise socket.timeout#cookie获取完毕#这一步是基于上一步的cookie,获取真是下载地址#debug_handler = urllib2.HTTPHandler(debuglevel=1)opener2 = urllib2.build_opener(RedirctHandler,handler)url2 = 'http://www.asp300.com/2012dll/DownBJ.jsp?CodeID=%d'%idreq2 = urllib2.Request(url=url2,headers=headers)try:html = opener2.open(req2,timeout=60)print '%s:获取下载地址成功'%time.ctime()except urllib2.URLError, e:if num_retries > 0 and hasattr(e,'code') and (500 <= e.code <600):return soft_url(url,headers,num_retries - 1)else:print 'SOFT_URL2 Error:', e.reasonraise MyErrorexcept socket.timeout:if num_retries > 0:return soft_url(url, headers, num_retries - 1)raise socket.timeoutreturn htmldef clicent():HOST = ''#这里填主机ip,自己根据情况修改PORT = 21567#这里填主机端口,自己根据情况修改BUFSIZ = 1024ADDR = (HOST,PORT)#创建套接字tcpCliSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)tcpCliSock.connect(ADDR)data = "ask for task"tcpCliSock.send(data)data = tcpCliSock.recv(BUFSIZ)return datadef main():headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 '}url = clicent()html = Download(url, headers)print '页面下载完成'title, size, summary_content, image_url = resolve(html)print '信息提取完成'id = 0for i in image_url:name = './image/image_cache%d.jpg' % iddownload_image(name, i, headers)print '图片下载完成%d' % idscreenshot(name, 52, 'jpeg')print '图片转换完成'id += 1download_url = soft_url(url, headers)print titleprint sizesummary_content = summary_content.replace(u'\u200b',u'')#unicode特殊字符'\u200b',不能转为gb2312print summary_content,type(summary_content)print summary_content.encode('gb2312')print image_urlprint download_urlif __name__ == '__main__':main()





这篇关于基于广域网的主从分布式爬虫系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866506

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

Seata之分布式事务问题及解决方案

《Seata之分布式事务问题及解决方案》:本文主要介绍Seata之分布式事务问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Seata–分布式事务解决方案简介同类产品对比环境搭建1.微服务2.SQL3.seata-server4.微服务配置事务模式1

Linux搭建Mysql主从同步的教程

《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi