在使用 scrapy 爬取 IT桔子公司信息,用来进行分析,了解 IT 创业公司的一切状况,以前使用 scrapy 写了一个默认线程是10的单个实例,为了防止被 ban IP 设置了下载的速度,3万多个公司信息爬了1天多才完成,如今想到使用分布式爬虫来提升效率。python
源码githupmysql
Python3.5
scrapy
scrapy_redis
redis
docker1.12
docker-compose
Kitematic
mysql
SQLAlchemy
安装 Docker
点这里去了解、安装;git
pip install scrapy scrapy_redis
;github
分析页面信息:
我须要获取的是每个「公司」的详情页面连接 和 分页按钮连接;redis
统一存储获取到的连接,提供给多个 spider
爬取;sql
多个 spider
共享一个 redis
list
中的连接;docker
# coding:utf-8 from bs4 import BeautifulSoup from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from scrapy_redis.spiders import RedisCrawlSpider from 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
说明:dom
class
继承了RedisCrawlSpider
而不是CrawlSpider
scrapy
start_urls
改成一个自定义的 itjuziCrawler:start_urls
,这里的itjuziCrawler:start_urls
就是做为全部连接存储到 redis
中的 key
,scrapy_redis
里也是经过redis
的 lpop
方法弹出并删除连接的;分布式
使用 SQLAlchemy
做为 ORM
工具,当表结构不存在时,自动建立表结构
增长了不少 User-Agent
,每个请求随机使用一个,防止防止网站经过 User-Agent
屏蔽爬虫
配置middlewares.py
scrapy_redis
redis
连接相关信息
在上面的「目录结构图」中有,Dockerfile
和docker-compose.yml
FROM python:3.5 ENV PATH /usr/local/bin:$PATH ADD . /code WORKDIR /code RUN pip install -r requirements.txt COPY spiders.py /usr/local/lib/python3.5/site-packages/scrapy_redis CMD /usr/local/bin/scrapy crawl itjuzi_dis
说明:
使用 python3.5
做为基础镜像
将/usr/local/bin
设置环境变量
映射 host
和 container
的目录
安装 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
version: '2' services: spider: build: . volumes: - .:/code links: - redis depends_on: - redis redis: image: redis ports: - "6379:6379"
说明:
使用第2版本的 compose
描述语言
定义了 spider
和 redis
两个 service
spider
默认使用当前目录的 Dockerfile
来建立,redis
使用 redis:latest
镜像建立,并都映射6379端口
启动 container
docker-compose up #从 docker-compose.yml 中建立 `container` 们 docker-compose scale spider=4 #将 spider 这一个服务扩展到4个,仍是同一个 redis
能够在 Kitematic
GUI 工具中观察建立和运行状况;
在没有设置 start_urls
时,4个 container
中的爬虫都处于饥渴的等待状态
如今给 redis
中放入 start_urls
:
lpush itjuziCrawler:start_urls http://www.itjuzi.com/company
4个爬虫都动起来了,一直爬到start_urls
为空
以上です!ありがとうございました!