Python36 使用Redis 构建分布式爬虫(未完)
很长时间未更新了,人懒了。
最近有不少的东西,慢慢写吧,最近尝试了一下python 使用Redis 来构建分布式爬虫;
单体爬虫有很多缺点,但是在学习过程中能够学习爬虫的基本理念与运行模式,在后期构建健壮的爬虫还是很有用的;获取代理,构造Header伪装,构造Referer..... 在分布式里一样一样的
分布式爬虫,听起来就很高大上啊,运行起来也的确高大上;
=======================================================================================================
安装Redis
1.官网下载redis的tar包
wget http://download.redis.io/releases/redis-4.0.9.tar.gz
2. 解压安装包到安装目录
tar xvf redis-4.0.9.tar.gz -C /usr/local/
3.cd /usr/local/redis-4.0.9
4. 编译安装
make
====================如果出现以下错误
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory
#include <jemalloc/jemalloc.h>
^
compilation terminated.
make[1]: *** [adlist.o] Error 1
make[1]: Leaving directory `/usr/local/redis-4.0.9/src'
make: *** [all] Error 2
则使用make MALLOC=libc
5. 测试是否安装成功
6. make test
======================make test 需要安装 tcl : yum -y install tcl
7. 测试成功
=======================================================================================================
Shell 操作
1. 连接Redis server
src/redis-cli #默认连接地址: 127.0.0.1:6379
src/redis-cli --help #帮助
src/redis-cli -h 192.168.209.145 # 连接远程Redis server 未加认证
src/redis-cli -h 192.168.209.145 -a passwd -p 6379 # 连接指定的信息服务器port=6379,password=passwd
2. 插入数据
==================
如果连接后未认证,则
auth ***** # * 为passwd
也可连接时认证
==================
set key value # 语法
set age 20
3.读取数据
get key # 语法
get age
"20"
=======================================================================================================
配置Redis.conf
以下是配置文件内容,大部分都是默认的;
更改:
bind 192.168.209.159 # 服务器ip, 如果是127.0.0.1则不能远程连接Redis
protected-mode no # 关闭保护模式
requirepass **** # 设置远程连接的密码
启动Redis src/redis-server 默认启动xxxxx
src/redis-server redis.conf 启动时加载配置文件
=======================================================================================================
Spider master 主要抓取URL的地址,并存入Redis
以下代码需要安装几个库,bs4, requests,redis,lxml
pip install 即可;
我使用的是pycharm IDE ,这几个包基本爬虫必备,基本功;
- #!/usr/bin/env python
- # coding:utf-8
- # @Time : 2018/3/21 22:44
- # @Author : maomao
- # @File : Mzitumaster.py
- # @Mail : mail_maomao@163.com
- from bs4 import BeautifulSoup
- import requests
- from redis import Redis
- import time
- con = Redis(host="192.168.209.145",port=6379,password="tellusrd")
- baseUrl = "http://www.mzitu.com/"
- URL = baseUrl + "all"
- def getResponse(url):
- contents = requests.get(url).text
- return BeautifulSoup(contents,'lxml')
- def genObjs(**kwargs):
- return kwargs
- def addRedis(key,value):
- con.lpush(key,value)
- def getRedis(key):
- value = con.rpop(key)
- if value:
- return eval(value.decode('utf-8'))
- return None
- def getImagePages(url):
- soup = getResponse(url)
- pages = soup.find("div",attrs={'class':'pagenavi'}).find_all('span')[-2].text
- return pages
- def getImagesUrl():
- soup = getResponse(URL)
- alltag = soup.find_all("a")
- for tag in alltag:
- url = tag.get('href')
- preurl = url.split('/')[-1]
- if preurl:
- endurl = baseUrl + preurl
- page = getImagePages(endurl)
- data = genObjs(title=tag.text,url=endurl,page=page)
- addRedis("objs",data)
- #### 以下两个自己测试用
- def writeHost(data):
- title = data['title']
- url = data['url']
- with open("mmurl.txt","a+",encoding="utf-8") as f:
- f.write(title+"\t \t"+url+"\n")
- def getValues():
- while True:
- datas = getRedis("objs")
- if datas:
- writeHost(datas)
- else:
- break
- if __name__ == "__main__":
- print(time.ctime())
- getImagesUrl()
- # getValues()
- print(time.ctime())
Spider slave 从Redis 中获取目标URL 地址并执行下载任务
- #!/usr/bin/env python
- # coding:utf-8
- # @Time : 2018/3/22 22:09
- # @Author : maomao
- # @File : Mzituspider.py
- # @Mail : mail_maomao@163.com
- from redis import Redis
- from bs4 import BeautifulSoup
- import requests
- con = Redis(host="192.168.209.145",port=6379,password="tellusrd")
- def getResponse(url):
- contents = requests.get(url).text
- return BeautifulSoup(contents,'lxml')
- def getRedis(key):
- value = con.rpop(key)
- if value:
- return eval(value.decode('utf-8'))
- return None
- def getValues():
- while True:
- datas = getRedis("objs")
- if datas:
- mmtitle = datas['title']
- page = datas['page']
- for i in range(1, 2):
- url = datas['url'] + "/" + str(i)
- contents = getResponse(url)
- imageurl = contents.find("div", attrs={"class": "main-image"}).find("img").get('src')
- print(imageurl)
- downImages(imageurl, url, mmtitle)
- else:
- break
- def downImages(url,referer,title):
- headers = {
- 'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
- 'Referer': referer,
- }
- image = requests.get(url,headers=headers,stream=True)
- name = url[-10:]
- print("正在下载: ",title)
- with open(name,'wb') as f:
- f.write(image.content)
- if __name__ == "__main__":
- getValues()
注: 以上部分运行测试没问题,最后的存储部分未写完,不想写;
自己的思路如下:
根据Title 建立独立的文件夹用来保存即可;
Python36 使用Redis 构建分布式爬虫(未完)的更多相关文章
- 基于Python,scrapy,redis的分布式爬虫实现框架
原文 http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...
- Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架
Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloop import tornado.web from myhas ...
- 《Redis官方文档》用Redis构建分布式锁
用Redis构建分布式锁 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简 ...
- Redis构建分布式锁
1.前言 为什么要构建锁呢?因为构建合适的锁可以在高并发下能够保持数据的一致性,即客户端在执行连贯的命令时上锁的数据不会被别的客户端的更改而发生错误.同时还能够保证命令执行的成功率. 看到这里你不禁要 ...
- 阿里云Centos7.6上面部署基于redis的分布式爬虫scrapy-redis将任务队列push进redis
Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的时候,单个服务器的处理能力就不能满足我们的需求了(无论是处理速度还是网络请 ...
- 在阿里云Centos7.6上面部署基于Redis的分布式爬虫Scrapy-Redis
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_83 Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的 ...
- Scrapy+redis实现分布式爬虫
概述 什么是分布式爬虫 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取. 原生Scrapy无法实现分布式的原因 原生Scrapy中调度器 ...
- 用Redis构建分布式锁-RedLock(真分布)
在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简单的实现其实只需采用稍微增 ...
- 使用redis构建分布式锁
Redis使用WATCH命令来代替对数据进行加锁,因为WATCH只会在数据被其他客户端抢先修改了的情况下通知执行了这个命令的客户端,但是不会阻止其他客户端对数据进行修改,所以这个命令被称为乐观锁. 但 ...
随机推荐
- docker部署验证码项目报错:at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
如果docker部署启动报错 java.lang.NullPointerException: nullat sun.awt.FontConfiguration.getVersion(FontConfi ...
- JAVA判断字符串中某个字符存在的个数
/** * 判断字符串中某个字符存在的个数 * @param str1 完整字符串 * @param str2 要统计匹配个数的字符 * @return */ public static int co ...
- MAVEN项目打包报错:Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on pr ...
- c++之一个方便的日志库
概述 本文演示环境: win10 + vs2017 日志,我用的很少,通常是用作动态库调试使用. 日志记录下来,基本就没看过,除非模块出现了问题. 使用cmake管理的项目 使用C++封装了C语言读写 ...
- 再谈多线程模型之生产者消费者(多生产者和多消费者 )(c++11实现)
0.关于 为缩短篇幅,本系列记录如下: 再谈多线程模型之生产者消费者(基础概念)(c++11实现) 再谈多线程模型之生产者消费者(单一生产者和单一消费者)(c++11实现) 再谈多线程模型之生产者消费 ...
- GCD is Funny(hdu 5902)
GCD is Funny Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 【剑指Offer】二叉搜索树的第k个结点 解题报告(Python)
[剑指Offer]二叉搜索树的第k个结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- Cookie、Session、Token、JWT
什么是认证(Authentication)------->就是验证当前用户的身份,证明"你是你自己" 互联网中的认证: 用户名密码登录 邮箱发送登录链接 手机号接收验证码 只 ...
- Google Chrome调整控制台的位置
众所周知,控制台是开发必备的工具,学会流畅的使用控制台会给我们的开发带来不一样的体验,但是控制台的位置有时却是困扰我们的一件事,控制台默认是在浏览器内,有时十分妨碍我们,那么有没有什么办法修改控制台的 ...
- Dimension reduction in principal component analysis for trees
目录 问题 重要的定义 距离 支撑树 交树 序 tree-line path 重要的性质 其它 Alfaro C A, Aydin B, Valencia C E, et al. Dimension ...