在Docker容器上利用Scrapy-Redis框架的分布式爬虫
目录一、概况二、系统设计1、分布式爬虫框架2、分布式爬虫流程三、系统实现与测试1、系统开发环境2、Docker集群部署3、爬虫实现与测试总结一、概况这段时间在本科毕设和考研复试,所以PAT甲的题目暂缓了,会及时更新,这篇是我的毕设,欢迎大家的指导和交流!本项目主要是Docker容器下利用Scrapy-Redis框架实现了分布式爬虫,爬取的是豆瓣图书的信息,然后在Django下,写了一个简易的图书搜
一、概况
这段时间在本科毕设和考研复试,所以PAT甲的题目暂缓了,会及时更新,这篇是我的毕设,欢迎大家的指导和交流!
本项目主要是Docker容器下利用Scrapy-Redis框架实现了分布式爬虫,爬取的是豆瓣图书的信息,然后在Django下,写了一个简易的图书搜索系统,这里图书搜索系统就不展示了,网上有很多的系统模板,主要介绍的是容器下的分布式爬虫实现。本科的论文相对而言我认为表达更全面更完善,所以在这里就是一个简易版本,重点在步骤和过程。
二、系统设计
1、分布式爬虫框架
分布式爬虫架构是由一个master服务器和多个slave服务器共同组成。master服务器和slave服务器之间可以通信,共享master端的redis数据库。同时将分布式爬虫框架中的服务器均搭建成容器,包括1个master容器、3个slave服务器以及一个用来查看mysql数据库中具体数据并方便操作的admin容器,共五个容器。
2、分布式爬虫流程
(1)爬虫预处理
首先,master端对豆瓣图书的各个标签进行爬取。在https://book.douban.com/tag/?view=type&icn=index-sorttags-all中列举了豆瓣图书的标签,如小说、外国文学等。在数据库中以https://book.douban.com/tag/小说的形式保存。
(2)master爬取url
master服务器负责解析豆瓣图书中的tags(标签)下的图书url,将每一个具体的图书url存入redis数据库
(3)slave爬取详情页
slave服务器端负责获取具体图书的url,爬取图书详情页的具体信息并将其转换成json格式,存入master端的redis数据库,使得各个slave服务器爬取获得的详情信息可以汇总。
三、系统实现与测试
1、系统开发环境
工具/环境 | 软件名称 |
---|---|
操作系统 | windows10 |
docker容器 | docker 20.10.6 |
docker容器下的操作系统 | ubuntu 20.10 |
开发语言 | python 3.8.6 |
浏览器 | firefox 88.0.1 |
数据库 | redis 4.0.9 |
数据库 | mysql 8.0.21 |
2、Docker集群部署
本系统采用一个master端与三个slave端的分布式爬虫框架进行实现与测试,其中master和slave均为容器,另外使用docker官方库中的admin镜像搭建myspider_admin(数据库图形化管理界面),在分布式爬虫完成后,对实验结果进行验证。
容器名 | 容器ID | IP地址 |
---|---|---|
master | ac74 | 172.17.0.2 |
slave1 | c32e | 172.17.0.3 |
slave2 | abfd | 172.17.0.5 |
slave3 | 33a8 | 172.17.0.6 |
myspider_admin | f84f | 172.17.0.4 |
这里的容器ID每个人都会不一样。
(1) Docker的安装
在安装docker完成后,输入以下命令对docker安装进行检验。
docker –version
输入以下命令,查看现有镜像(image),ps -a查看目前存在的容器,发现有docker自带的Ubuntu,Admin等镜像。
docker image ls
docker ps -a
(2) 利用Ubuntu镜像创建容器Master
命令:
docker run -it ubuntu /bin/bash –name master
安装redis,python3,mysql,pip,scrapy-redis等一些基本软件和库。测试master登录redis和mysql数据库,由于redis和mysql都是在容器上运行,不能用本地连接(127.0.0.1),所以在配置相关软件时,要修改其配置文件,将其修改成容器的IP地址。配置完毕后,测试连接
(3) 创建myspider_admin
利用admin镜像创建容器myspider_admin,并连接到master的mysql数据库,开放8080端口,方便对mysql数据库里的数据访问和下载。在master下创建新的数据库后,进行简单测试,可以在admin中查看到master的数据操作。
(4) 创建slave容器
将容器master映射成镜像myspider,并用myspider的镜像创建容器slave1连接master,利用命令:
docker run -tid --name slave1 --link master my_spider
对slave1进行测试后,发现可以登录master的redis和mysql的数据库,即表示,slave1和master通信完成,可共享master的数据库。紧接着再创建容器slave2,slave3,和slave1的创建方式一样,利用master所映射的镜像myspider,并连接master,并对其进行测试,测试成功
这里就把分布式爬虫的框架部署完毕。
3、爬虫实现与测试
(1) 爬虫预处理
对豆瓣图书的标签进行爬取。首先定义Http请求中的Headers相关参数,浏览器信息User-agent,以及url:https://book.douban.com/tag/?view=type&icn=index-sorttags-all。并发送一个完整的请求,返回200,成功处理。当爬虫过于频繁的时候,会返回403错误,显示异常IP的登录。随后连接redis数据库,并读取网页中
下的所有 ,即读取所有标签,并存入redis数据库。(2)master端爬取图书的url
master端负责爬取redis数据库中book标签下的具体图书url,并再次存入redis数据库。master采用的是scrapy的爬虫框架,所以进入master容器后,确认安装scrapy和scrapy-redis完毕后,利用命令scrapy startproject douban_master(项目名)创建master的爬虫项目。
scrapy爬虫框架中包括部署爬虫项目的配置文件scrapy.cfg和4个组件文件分别为items.py、middlewares.py、pipelines.py、settings.py,以及一个管理多个爬虫的目录spiders。
① items.py
此文件类似于django中的models.py,用于声明数据类型,用来保存数据。由于master端只需要对url进行爬虫,所以在items.py文件中仅存放url这一数据。
② middleware.py
爬虫中间件可以对请求和响应进行处理。from_crawler函数表示创建爬虫。process_spider_input函数表示在response对象交给spider爬虫进行解析前,可以对response进行处理,只能返回None或者抛出一个异常,以及process_spider_output函数表示从response返回的结果中,对后续的item和request进行处理,必须返回request或者item对象。同时,为了防止反爬虫,可以在请求被发起之前对request进行处理,设置请求头一些字段User_agent_type。
③ pipelines.py
管道文件的作用是将每一个item对象进行存储,存进数据库如mysql,redis,mongodb中。代码中使用正则表达式判断url是否有效,并把有效url写入redis数据库。
④ settings.py
此文件是对爬虫项目进行配置的文件。scrapy默认遵守robot.txt协议规则,robots规定了一个网站中,哪些地址可以请求,哪些地址不请求,在配置时,选择False,表示不遵守这个协议。下载延时是请求和请求之间的间隔,降低爬取速度,可以避免被识别到在对豆瓣图书进行爬虫操作。随后配置默认的请求头Headers,自定义的pipelines,指定使scrapy-redis的去重,调度器。在redis中保持scrapy-redis用到的各个队列,从而允许暂停和暂停后恢复,也就是不清理redis queues。最后指定排序爬取地址时使用的队列,默认的按优先级排序(scrapy默认),由sorted set实现的一种非FIFO、LIFO方式。
⑤ spiders目录
这是管理多个爬虫文件的目录,具体的爬虫逻辑都在该目录内。在master端创建book_master.py,自定义爬虫名称name,在运行爬虫项目时,是通过这个唯一值name运行的。随后设置允许访问的网站域名book.douban.com、连接redis数据库信息、爬虫的初始url。在爬虫启动之后,Engine就会提取第一个url,将url构造成一个request对象,交给调度器。在url的请求成功后,便可以解析每个tag下对应的图书详情信息中,及其所对应的url,如:https://book.douban.com/subject/27080946/,将每一个详情页的请求对象,yield到调度器队列中,等待被执行。最后获取下一页的地址,循环,爬取每一本图书的url。
(3) slave端爬取图书详情信息
首先获取每一个url,通过此url对图书的详细信息进行爬取,并采用json格式存入redis数据库中。进入slave容器,与master容器一样,创建scrapy项目,同样拥有4个组件文件,和管理爬虫的spiders的目录。代码实现方式与master端相同,两者只在爬取的数据内容上具有差别。最后将爬取的内容以json格式存入redis数据库中,直到redis中的url被全部读取完毕后停止。
最后将redis中存储的每个url所对应的数据转存到mysql中。首先,在mysql中建立数据库doubandb,并建立相应的表books。接着在Python代码中,分别与redis数据库和mysql数据库进行连接,并使用游标的方式读入相关数据。从redis中读取,book_detail:items中的key和value值,将redis中的url所对应的json数据格式的value值解析,组成sql语句,将每一个属性指定其参数,执行insert语句,并将事务提交,直到redis中所有book_detail中的信息被读完,测试成功。
总结
对于爬虫频繁的豆瓣网站反馈的403问题,还可以利用代理池的代理IP方式解决。整个过程需要一点Linux的基础知识和爬虫代码能力。欢迎大家的指导和交流!
更多推荐
所有评论(0)