# !控制主机程序

'''主机发送爬虫网址,从机进行爬取信息,并返回给主机'''

#本次优化主要是:由于发送url与爬取url速度差异较大,造成发送url的队列中存在数据较多,占用内存。

# 新方案是当发送url队列中数量大于200条时,暂不发送url任务;

# 当new-urls数量大于200条时,分批存储在临时文件夹下,减小内存占用

# 当old_urls数量大于200条时,保存到本地文件夹

import pickle, hashlib, sys, codecs, time, sys,tempfile,os,pickle

from multiprocessing import Process, Queue

from multiprocessing.managers import BaseManager

class url_manager(object):

def __init__(self):

self.new_urls = self.load_process('newurls.txt')

self.old_urls = self.load_process('oldurls.txt')

def add_new_url(self, url):#此处判定url可以只判断是否在old_urls里即可

if url not in self.old_urls:

self.new_urls.add(url)

def add_new_urls(self, url):

if url!=None:

for i in url:

self.add_new_url(i)

def has_new_url(self):

return len(self.new_urls) != 0

def get_new_url(self):

a = self.new_urls.pop()

self.old_urls.add(a)

return a

# def md_url(self, url):

# a = hashlib.md5()

# a.update(bytes(url, encoding='utf-8'))

# return a.hexdigest()

def save_process(self, path, data):

''' print('is saving fidle:',path)'''

with open(path, 'ab+')as f:

pickle.dump(data, f)

f.close()

def load_process(self, path):

''' print('is loading file:%s',path)'''

print('从文件加载进度:%s' % path)

try:

with open(path, 'rb')as f:

data = pickle.load(f)

return data

f.close()

except:

print('is not created: ', path)

return set()

class data_save(object):

def __init__(self):

self.date = time.strftime(" %Y-%m-%d-%H-%M-%S", time.localtime())

self.filepath = 'baike%s.txt' % (self.date)

self.urlpath = 'url%s.txt' % (self.date)

self.data = []

def data_saving(self, path, datas):

self.data.append(datas)

if len(self.data) > 5 or datas == 'end':

with open(path, 'a+', encoding='utf-8') as f:

for i in self.data:

f.write(i)

f.write(r' ')

f.close()

self.data = []

class controller(object): # 建立网络队列

def __init__(self):

self.url_manag = url_manager()

self.dataing = data_save()

def multi_processmanager(self, url_q, result_q):

BaseManager.register('get_task_queue', callable=url_q)

BaseManager.register('get_result_queue', callable=result_q)

manager = BaseManager(address=('127.0.0.1', 8100), authkey='baike'.encode())

manager.start()

return manager

def send_url1(self, url_q, send_url_q, root_url): # 将接收到的新url队列,保存到url_manager,并发送给控制节点

self.url_manag.add_new_url(root_url)

num1 = 0

while True:

if not send_url_q.empty(): # 新接收到的urls,全部转入new_urls,进行爬虫

urls = send_url_q.get()

if urls == 'end':

self.url_manag.save_process(self.dataing.urlpath, self.url_manag.old_urls) # 保存已爬取的网页

break

self.url_manag.add_new_urls(urls)

if self.url_manag.has_new_url():

old_url = self.url_manag.get_new_url()

url_q.put(old_url) # 发送到网络队列,传输给爬虫节点

num1 += 1

print(num1, 'is running:', old_url)

def data_manager(self, result_q, send_data_q,

send_url_q): # 将网络上的爬虫节点传输的结果队列的数据和url分发到各控制节点的数据队列(用于保存到本地)和url队列(用于传输给url_manager),

while True:

if not result_q.empty():

data = result_q.get() # 接收到的爬虫网站数据包括data和url两类

if data[0] == 'end' or data[1] == 'end':

send_data_q.put('end') # 发送data数据到存储进程

send_url_q.put('end') # 发送url到进程sen_url中,

break

send_data_q.put(data[0]) # 发送data数据到存储进程

if data[1] != 'Null':

send_url_q.put(data[1]) # 发送url到进程sen_url中,

def data_saves(self, data_q): # 保存数据的进程

while True:

if not data_q.empty():

data1 = data_q.get()

if data1 == 'end':

break

self.dataing.data_saving(self.dataing.filepath, data1)

def send_url(self, url_q, send_url_q, root_url):#保存newurl和 oldurl到本地文件

self.url_manag.add_new_url(root_url)

num1,num2,num3=0,0,0

temp = tempfile.TemporaryFile()#创建临时文件夹,保存newurl

filename=temp.name

urls=[]

while True:

if self.url_manag.has_new_url():

old_url = self.url_manag.get_new_url()

url_q.put(old_url) # 发送到网络队列,传输给爬虫节点

num1 += 1

print(num1, 'is sending:', old_url)

if not send_url_q.empty(): # 新接收到的urls,全部转入new_urls,进行爬虫

urls = send_url_q.get()

if urls == 'end': # 或者爬虫结束时,进行保存本地

self.url_manag.save_process(self.dataing.urlpath, self.url_manag.old_urls)

self.url_manag.old_urls = set()

break

elif urls!=[]:

if num2 < 10:#刚开始爬虫时,数据直接添加到队列

self.url_manag.add_new_urls(urls)

num2 += 1

continue

else:

if len(urls)>8:#urls数据较大时,loads会报run out input

#self.url_manag.add_new_urls(urls)

for i in urls:

data1 = pickle.dumps(i)

temp.write(data1) # newurl全部保存到临时文件夹,从临时文件夹存取url

temp.write(b' ')

else:

data1=pickle.dumps(urls)

temp.write(data1)# newurl全部保存到临时文件夹,从临时文件夹存取url

temp.write(b' ')

if url_q.qsize() < 100: # 当发送任务url队列中数据较少时,添加数据

temp.seek(0)

lines = temp.readlines()

if num3 < len(lines):

urldata = lines[num3]

num3 += 1

url1 = pickle.loads(urldata)

if isinstance(url1, list):

self.url_manag.add_new_urls(url1)

else:

url0 = []

url0.append(url1)

self.url_manag.add_new_urls(url0)

if len(self.url_manag.old_urls) > 100: # old_urls中数据较多,进行保存本地

self.url_manag.save_process(self.dataing.urlpath, self.url_manag.old_urls)

self.url_manag.old_urls = set()

url_q = Queue() # 控制节点发给爬虫节点的队列

result_q = Queue() # 爬虫节点发送的网站数据

def url_q1():

return url_q

def result_q1():

return result_q

if __name__ == '__main__':

sys.setrecursionlimit(1000000) # 不加时,爬虫容易出现递归错误,

data_q = Queue() # 网站数据中关于title,reffer等数据,用于保存数据的队列

urlmanager_q = Queue() # 网址数据发送给url_manager的队列

url = r'https://baike.baidu.com/item/%E5%8C%96%E5%AD%A6/127240'

url1=r'https://baike.baidu.com/item/%E8%87%AA%E7%84%B6%E7%A7%91%E5%AD%A6/260539'

a = controller()

manag = a.multi_processmanager(url_q1, result_q1)

url_queue = manag.get_task_queue()

result_queue = manag.get_result_queue() # 获取网络队列

p1 = Process(target=a.send_url, args=(url_queue, urlmanager_q, url,))

p2 = Process(target=a.data_manager, args=(result_queue, data_q, urlmanager_q,))

p3 = Process(target=a.data_saves, args=(data_q,))

p1.start()

p2.start()

p3.start()

p1.join()

p2.join()

p3.join()

python爬虫百度百科-python每日一题:网络爬虫百度百科相关推荐

  1. 玩转python网络爬虫黄永祥pdf下载_Python网络爬虫从入门到实践pdf

    Python网络爬虫从入门到实践 内容简介 本书将介绍如何使用Python编写网络爬虫程序获取互联网上的大数据.本书包括三部分内容:基础部分.进阶部分和项目实践.基础部分(第1~6章)主要介绍爬虫的三 ...

  2. python网络爬虫与信息提取_北京理工大学_Python网络爬虫与信息提取(一)

    学习 北京理工大学 嵩天 课程笔记 课程体系结构: 1.Requests框架:自动爬取HTML页面与自动网络请求提交 2.robots.txt:网络爬虫排除标准 3.BeautifulSoup框架:解 ...

  3. Java网络爬虫入门:第01课:网络爬虫原理

    引言 随着互联网的迅速发展,网络资源越来越丰富,信息需求者如何从网络中抽取信息变得至关重要.目前,有效的获取网络数据资源的重要方式,便是网络爬虫技术.简单的理解,比如您对百度贴吧的一个帖子内容特别感兴 ...

  4. 爬虫基础(1)什么是网络爬虫

    文章目录 一. 认识网络爬虫 二. 网络爬虫的组成 三. 网络爬虫的类型 1. 通用网络爬虫 2. 聚焦网络爬虫 3. 增量式网络爬虫 4. 深层网络爬虫 (1)静态网页 (2)深层页面和表层页面 ( ...

  5. java爬虫面试题_使用Java实现网络爬虫

    网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 另外一些不常使用的名字还有蚂蚁.自动索引.模 ...

  6. 分布式网络爬虫关键技术分析与实现一网络爬虫相关知识介绍

    搜索引擎发展的历史过程与发展现状 1搜索引擎的发展的历史 1990年以前,没有任何人能搜索互联网.所有搜索引擎的祖先,是1990年由Montreal的McGill University学生Alan E ...

  7. 【爬虫】力扣每日一题每天自动邮件提醒!!!

    使用python实现了一个力扣每日一题每天自动邮件提醒的小爬虫,小但实用!!! 文章目录 A.需求来源与分析 B.技术角度分析 C.具体分析步骤 1.接口协议分析 2.发邮件 3.写crontab放服 ...

  8. Python网络爬虫从入门到实践 -- chapter 1 -- 网络爬虫入门

    1 Robots协议 Robots协议(爬虫协议)全称网络爬虫排除标准,网站通过Robots协议告诉搜索引擎哪些页面可以抓取(Allow:/),哪些不能抓取(Disallow:/).这个协议是国际互联 ...

  9. 网络爬虫python的特点有哪些_为什么写网络爬虫天然就是择Python而用

    关于这个问题,老猿就先从自己的经历讲起吧.很多年前,大约11年前,老猿我接手了一个搜索引擎的网络爬虫,那是一个用C++写的通用搜索引擎的爬虫.C++的语言,多线程的实现,爬虫的运行效率非常高.但是,找 ...

  10. python网络爬虫权威指南 第2版 pdf微盘_python网络爬虫权威指南第2版pdf-Python网络爬虫权威指南第2版中文PDF+英文PDF+源代码下载_东坡手机下载...

    本书不仅介绍了网页抓取,也为抓取.转换和使用新式网络中各种类型的数据提供了全面的指导.虽然本书用的是Python编程语言,涉及Python的许多基础知识,但这并不是一本Python 入门书. 如果你完 ...

最新文章

  1. 计算机网络画出发送窗口变化,2010年7月计算机网络原理试题及答案
  2. java注解_Java注解教程及自定义注解
  3. java.io.IOException: InvalidResourceRequestException: Invalid resource request
  4. 8.11 NOIP模拟测试17 入阵曲+将军令+星空
  5. 用lnmp.org中的lnmp下安装ftp(pureftp)
  6. python贪吃蛇游戏设计答辩_python编写贪吃蛇游戏
  7. 记录mysql in和not in 效率低下的问题
  8. win10主机ping不通win10虚拟机
  9. glob patterns
  10. 【转载】CodeWarrior IDE使用Tips-如何编译生成和调用静态库
  11. javascript开发HTML5游戏--斗地主(单机模式part3)
  12. 10分钟教你用Python实现微信翻译机器人
  13. cocos Creator android 上传图片与数据
  14. ha 配置ssl_烂泥:haproxy学习之https配置
  15. insserv: Starting xx depends on plymouth and therefore on system facility `$all'
  16. 第5.2节 应用工具包得到幅相加权
  17. 友盟的常见使用----三方登陆、分享和“埋点”(友盟统计)
  18. 安全技术的发展:物理隔离三步曲
  19. HCIE北京考场体验报告
  20. 问题:windows---笔记本外接显示器,在系统更新后,外接显示器没有反应,右键打开显示设置,点击检测后提示未检测到其他显示器

热门文章

  1. 洛谷P1424小鱼的航程改进版
  2. 安装MySQL时出现黄色感叹号,提示3306已被占用
  3. eclipse 和 myeclipse 字符编码设置
  4. 实验五 Java网络编程及安全 实验报告 20135232王玥
  5. Android中用 adb 命令操作数据库
  6. 使用mod_proxy_balancer实现负载均衡
  7. python与人工智能编程-五大人工智能流行编程语言对比,只要学会一种绝对不亏!...
  8. python入门教程非常详细-Python编程入门教程:从入门到高级,非常详细
  9. python画三维温度散点图-Python 绘制酷炫的三维图步骤详解
  10. php和python哪个用了开发web好-web开发选择Python还是PHP好呢?