scrapy_redis 和 docker 实现简单分布式爬虫
admin
2023-07-31 00:46:19
0

简介

在使用 scrapy 爬取 IT桔子公司信息,用来进行分析,了解 IT 创业公司的一切情况,之前使用 scrapy 写了一个默认线程是10的单个实例,为了防止被 ban IP 设置了下载的速度,3万多个公司信息爬了1天多才完成,现在想到使用分布式爬虫来提高效率。

源码githup

技术工具:Python3.5 scrapy scrapy_redis redis docker1.12 docker-compose Kitematic mysql SQLAlchemy

准备工作

  1. 安装 Docker 点这里去了解、安装;
  2. pip install scrapy scrapy_redis;

代码编写

  1. 分析页面信息:
    我需要获取的是每一个「公司」的详情页面链接 和 分页按钮链接;
  2. 统一存储获取到的链接,提供给多个 spider 爬取;
  3. 多个 spider 共享一个 redis list 中的链接;

目录结构图

juzi_spider.py

1234567891011121314151617181920212223242526272829 # coding:utf-8 from bs4 import BeautifulSoupfrom scrapy.linkextractors import LinkExtractorfrom scrapy.spiders import CrawlSpider, Rule from scrapy_redis.spiders import RedisCrawlSpiderfrom itjuzi_dis.items import CompanyItem  class ITjuziSpider(RedisCrawlSpider):    name = \’itjuzi_dis\’    allowed_domains = [\’itjuzi.com\’]    # start_urls = [\’http://www.itjuzi.com/company/157\’]    redis_key = \’itjuziCrawler:start_urls\’    rules = [        # 获取每一页的链接        Rule(link_extractor=LinkExtractor(allow=(\’/company?page=d+\’))),        # 获取每一个公司的详情        Rule(link_extractor=LinkExtractor(allow=(\’/company/d+\’)), callback=\’parse_item\’)    ]     def parse_item(self, response):        soup = BeautifulSoup(response.body, \’lxml\’)          .         .省略一些处理代码         .        return item

说明:

  1. class 继承了RedisCrawlSpider 而不是CrawlSpider
  2. start_urls 改为一个自定义的 itjuziCrawler:start_urls,这里的itjuziCrawler:start_urls 就是作为所有链接存储到 redis 中的 key,scrapy_redis 里也是通过redislpop方法弹出并删除链接的;

db_util.py

使用 SQLAlchemy 作为 ORM 工具,当表结构不存在时,自动创建表结构

middlewares.py

增加了很多 User-Agent,每一个请求随机使用一个,防止防止网站通过 User-Agent 屏蔽爬虫

settings.py

配置middlewares.py scrapy_redis redis 链接相关信息

部署

在上面的「目录结构图」中有,Dockerfiledocker-compose.yml

Dockerfile

1234567 FROM python:3.5ENV PATH /usr/local/bin:$PATHADD . /codeWORKDIR /codeRUN pip install r requirements.txtCOPY spiders.py /usr/local/lib/python3.5/sitepackages/scrapy_redisCMD /usr/local/bin/scrapy crawl itjuzi_dis

说明:

  • 使用 python3.5作为基础镜像
  • /usr/local/bin设置环境变量
  • 映射 hostcontainer 的目录
  • 安装 requirements.txt
  • 特别要说明的是COPY spiders.py /usr/local/lib/python3.5/site-packages/scrapy_redis,将 host 中的 spiders.py 拷贝到container 中的 scrapy_redis 安装目录中,因为 lpop 获取redis 的值在 python2中是 str 类型,而在 python3中是 bytes 类型,这个问题在 scrapy_reids 中需要修复,spiders.py 第84行需要修改;
  • 启动后立即执行爬行命令 scrapy crawl itjuzi_dis

docker-compose.yml

1234567891011121314 version: \’2\’services:  spider:    build: .    volumes:     .:/code    links:     redis    depends_on:     redis  redis:    image: redis    ports:     \”6379:6379\”

说明:

  • 使用第2版本的 compose 描述语言
  • 定义了 spiderredis 两个 service
  • spider默认使用当前目录的 Dockerfile 来创建,redis使用 redis:latest 镜像创建,并都映射6379端口

开始部署

启动 container

12 dockercompose up #从 docker-compose.yml 中创建 `container` 们dockercompose scale spider=4 #将 spider 这一个服务扩展到4个,还是同一个 redis

可以在 Kitematic GUI 工具中观察创建和运行情况;

在没有设置 start_urls 时,4个 container 中的爬虫都处于饥渴的等待状态

现在给 redis 中放入 start_urls:

1 lpush itjuziCrawler:start_urls http://www.itjuzi.com/company

4个爬虫都动起来了,一直爬到start_urls为空

以上!


相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...