python爬虫入门 ✦ 乞丐版scrapy_redis分布式 + 增量式爬虫的实现

此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉。

1.开发环境

为什么要选择Redis来做分布式爬虫呢??主要的原因有两点:
1、Redis基于内存,速度快
2、Redis是非关系型数据库,Redis中集合,存储每个request的指纹

正因为Redis上述的两个特点,用redis做分布式爬虫就可以多台主机共享1个爬取队列
该项目用到:Pycharm + scrapy +Redis + Mysql,需要动手跟着操作的小伙伴可以先安装一下哦。

2.项目案例具体展现

Redis有几种架构模式,我这里选择的是最简单的一种——单机版(即一个master、其余为slave)
既然是分布式,那就准备大于或等于2台的主机。
本次开发环境我用了4台主机。在几位小伙伴的帮忙下实现了项目,感谢他们。经测试,

耗时2分钟爬虫获取的某房产*家的数据为3000条并存入数据库。
耗时60分钟爬虫获取的某房产*家的数据为85000条并存入数据库。
耗时600分钟,暂未测试…

3.注意事项 + Mysql注意事项!!

在这里再说一下项目实现的具体事项。
1.一台主机作为master,其他主机访问到master主机。
2.redis的指纹存放到和获取的数据保存到master主机。
!!!
所以,就有了下面这一步。
因为使用的是ubuntu系统,Mysql的权限是除本机外其他主机无法连接。
这里用的方法是创建一个新的数据库用户,用于给其他主机连接访问master的数据库。
所以需要如下操作一番,打开权限。

> 1. sudo -i
> 2. cd /etc/mysql/mysql.conf.d/
> 3. vim /mysqld.cnf
> 4. #bind-address =127.0.0.1  #仅本机连接,注释掉这句话。
> 5. exit
> 6. /etc/init/mysql/ mysql restart
> 7. mysql -uroot -p******
> 8. grant all privileges on *.* to 'sunrisecai(创建新用户)'@'%'
	-identified by ‘'填写用户密码'
	-with grant option;
> 9.flush privileges;
用创建的新用户登录
> 10.mysql -usunrisecai -p******
> 11.show databases;(如果看到有数据库,那创建新用户就成功了)

至此,已经可以成功访问master的数据库了。

4.核心代码 + 数据存储

首先!你得将代码写成scrapy的正常项目的抓取。
然后!就可以照着下面动手更改为分布式抓取了。

1.更改为Redis的代码

以下代码添加到settings.py
# settings.py
# 1.重新指定调度器: 启用Redis调度存储请求队列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 2.重新指定去重机制: 使用scrapy_redis的去重机制。确保所有的爬虫通过Redis去重
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 3.不清除Redis队列: 暂停/恢复/断点续爬,True:不清除  False:清除
SCHEDULER_PERSIST = True

# 4.指定连接到redis时使用的端口和地址
## 这里需要注意,master填写localhost,,slave填写的是master的主机IP
REDIS_HOST = 'localhost'
REDIS_PORT = 6379

# 最后千万不要忘记添加管道。
# 5.redis管道
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 200
}

以下代码添加到settings.py

2.存储到Mysql的代码

  1. 在pipelines.py添加Mysql连接
  2. 添加到管道
## pipelines.py
import pymysql
# mysql的具体设置在settings.py,所以这里需要导入该模块
from . settings import *

class MaoyanMysqlPipeline(object):
    def open_spider(self, spider):
        self.db = pymysql.connect(
            host=MYSQL_HOST,
            user=MYSQL_USER,
            password=MYSQL_PWD,
            database=MYSQL_DB,
            charset=MYSQL_CHAR
        )
        self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        # 插入数据
        ins = 'insert into 数据表名称 values(%s,%s,%s,%s)'
        L = [
            item['xxx'], item['xxx'], item['xxx'], item['xxx'],
        ]
        self.cursor.execute(ins, L)		# 提交操作
        self.db.commit()				# 写入数据库
        return item

    def close_spider(self,spider):
        self.cursor.close()				# 关闭连接
        self.db.close()

## settings.py
## 在该代码最下面添加以下代码
MYSQL_HOST = 'localhost'	#注:master填localhost,slave主机填写master的主机IP
MYSQL_USER = 'sunrisecai'
MYSQL_PWD = '******'
MYSQL_DB = '数据库名称'
MYSQL_CHAR = 'utf8'

3.存储到Mongodbl的代码

  1. 在pipelines.py添加Mysql连接
  2. 添加到管道
## pipelines.py
import pymongo
# Mongodb具体设置在settings.py,所以这里需要导入该模块
from . settings import *


class LianjiaPipeline(object):
    def process_item(self, item, spider):
        return item

# mongodb存储
class MaoyanMongodbPipeline(object):
    def __init__(self):
        host = MONGODB_HOST,
        port = MONGODB_PORT,
        dbname = MONGODB_DBNAME,
        sheetname = MONGODB_SHEETNAME
		
		# 连接到Mongodb
        client = pymongo.MongoClient(host, port)
        db = client[dbname[0]]  # 传递过来的数据是集合,不是字符串
        self.post = db[sheetname]

    def process_item(self, item, spider):
        # 将字典文件存入 monogodb
        data = dict(item)
        self.post.insert(data)
        return item

## settings.py
## 在该代码最下面添加以下代码
MONGODB_HOST = 'localhost'	#注:master填localhost,slave主机填写master的主机IP
MONGODB_PORT = 27017
MONGODB_DBNAME = '数据库名'
MONGODB_SHEETNAME = '集合名'

至此,本项目案例就可以成功运行了。
完整项目案例代码可以留下你的邮箱,我再发送给你。
因个人能力不足,难免有错误之处,所以恳请各位指正。。

发布了34 篇原创文章 · 获赞 210 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_45081575/article/details/100062959