在使用 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
爲空
以上です!ありがとうございました!