天天看點

關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作

關于爬蟲平台的架構設計實作和架構的選型(一)

關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作

首先來看一下一個爬蟲平台的設計,作為一個爬蟲平台,需要支撐多種不同的爬蟲方式,是以一般爬蟲平台需要包括

1、 爬蟲規則的維護,平台在接收到爬蟲請求時,需要能按照比對一定的規則去進行自動爬蟲

2、 爬蟲的job排程器,平台需要能負責爬蟲任務的排程,比如定時排程,輪詢排程等。

3、 爬蟲可以包括異步的海量爬蟲,也可以包括實時爬蟲,異步爬蟲指的是爬蟲的資料不會實時傳回,可能一個爬蟲任務會執行很久。 實時爬蟲指爬的資料要實時傳回,這個就要求時間很短,一般适合少量資料的爬蟲。

4、 爬蟲好的資料可以生成指定的檔案,比如csv檔案,json檔案等,然後通過資料處理引擎做統一處理,比如csv檔案可以通過資料交換落入大資料平台,或者爬蟲好的資料也可以丢入kafka中,然後再通過流式處理任務(spark或者storm,flink)做爬蟲資料的清洗和處理,處理完的資料,可以入到資料庫中。

關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作
下圖就是在平台設計時,爬蟲處理的一個流程,這個裡面包含了實時爬蟲,異步爬蟲。
關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作
根據上圖的處理流程,我們可以把架構圖進一步演進下
關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作
時序圖如下:
關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作

我們這裡先介紹異步爬蟲,爬蟲的架構很多,異步爬蟲一般用的比較多就是scrapy。

首先安裝scrapy

pip install scrapy
      

  

安裝完成後,就可以通過指令行建立一個基于scrapy的爬蟲項目,我們以爬取應用寶中理财類APP的名稱為示例

關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作

建立爬蟲項目的指令行指令:

scrapy startproject zj_scrapy
      

然後在指令行中,進入到建立的zj_scrapy目錄下

cd zj_scrapy      
執行      
scrapy genspider sjqq “sj.qq.com” 
      
建立一個爬蟲      
爬蟲建立好了後,可以使用IDE打開建立好的python項目,比如用idea(需要安裝python插件,預設沒有安裝)打開我們建立好的項目      
關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作
項目建立好了後,會預設生成一些模闆代碼檔案      
1、 items.py      
items用于存儲字段的定義。即爬取的内容存與item類中,在這裡我們定義了一個name字段。

      
# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class ZjScrapyItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()
    pass
      
2、 spider檔案編寫      
這個檔案一般在spiders 這個package下面,預設會繼承scrapy.Spider

      
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import HtmlResponse

from zj_scrapy.items import ZjScrapyItem


class SjqqSpider(scrapy.Spider):
    name = 'sjqq'
    allowed_domains = ['sj.qq.com']
    start_urls = ['https://sj.qq.com/myapp/category.htm?orgame=1&categoryId=114']

    def parse(self, response:HtmlResponse):
        name_list =  response.xpath('/html/body/div[3]/div[2]/ul/li')
        print("=============",response.headers)
        for each in name_list:
            item = ZjScrapyItem()
            name = each.xpath('./div/div/a[1]/text()').extract()
            item['name'] = name[0]
            yield item
        pass
      

  關于這段代碼的解釋如下:

關于爬蟲平台的架構設計實作和架構的選型(一) 關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作
3、 pipeline檔案編寫      
pipeline檔案一般用于對處理好的爬蟲結果資料做處理,可以入到資料庫中,也可以生成到指定的檔案中,process_item 方法就是對資料做處理的。      
另外pipeline 還包含了__init__和close_spider 兩個方法。__init__ 用于做初始化處理。  close_spider 用于執行結束時的操作處理。比如資料寫入資料庫或者檔案後,對資料庫做連結關閉或者檔案流做關閉操作等。      
# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


class ZjScrapyPipeline(object):
    def process_item(self, item, spider):
        print("+++++++++++++++++++",item['name'])
        print("-------------------",spider.cc)
        return item
      
4、 setting檔案修改      
setting檔案中存放的是爬蟲的配置,常用的配置一般可以包括      
1)、ITEM_PIPELINES的配置,比如      
ITEM_PIPELINES = {

    'zj_scrapy.pipelines.ZjScrapyPipeline': 300,

}      
這裡的300代表了一個優先級,數值範圍一般在0-1000,這個數值确定了運作的順序,數字越小,優先級越高。      
2)、字元集配置,可以通過FEED_EXPORT_ENCODING指定字元集      
FEED_EXPORT_ENCODING = 'utf-8'      
3)、CONCURRENT_REQUESTS配置Scrapy執行的最大并發請求數      
# Configure maximum concurrent requests performed by Scrapy (default: 16)

CONCURRENT_REQUESTS = 32      
4)配置請求的header,可以通過DEFAULT_REQUEST_HEADERS來進行配置      
DEFAULT_REQUEST_HEADERS = {

  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',

  'Accept-Language': 'en',

}      
5、 本地執行爬蟲      
在上面的都做完後,可以通過執行指令行scrapy crawl sjqq -o items.csv 來在本地運作爬蟲,sjqq 就是前面指定的爬蟲名,-o items.csv 表示生成一個csv檔案。      
運作完成後,可以看到爬取的内容已經寫到了指定的檔案中。

      
在運作時,可以通過-a 指定自定義的參數,比如scrapy crawl sjqq -o items.csv -a cc=scrapttest      
在這條執行指令中,我們指定了一個cc參數等于scrapttest,在Pipeline      
中,我們可以通過代碼擷取這個參數

      
class ZjScrapyPipeline(object):
    def process_item(self, item, spider):
        print("+++++++++++++++++++",item['name'])
        print("-------------------",spider.cc)
        return item
      
在代碼中,我們通過spider.cc 就可以擷取到這個參數的值,然後在運作日志可以看到,我們列印出來了這個參數值。

      
通過這種方式,我們就解決了爬蟲運作時,參數的的動态傳遞問題。      
6、 爬蟲部署到服務端      
安裝scrapyd       
pip install scrapyd       
安裝scrapyd-deploy      
pip install scrapyd-client      
scrapyd 是scrapy的爬蟲服務端,安裝完成後,執行scrapyd可以啟動服務端。      
啟動時預設端口為6800

      
啟動後,通過浏覽器可以通路http://localhost:6800/

      
服務端啟動後,就可以通過scrapyd-deploy 來送出部署開發好的爬蟲了。      
scrapyd-deploy <target> -p <project>  --version <version>      
部署成功後,就可以看到自己的爬蟲項目了

      
7、 建立服務端的爬蟲任務      
如果是在linux指令下,可以通過      
curl http://localhost:6800/schedule.json -d project= zj_scrapy -d spider=sjqq
      
來送出一個爬蟲任務,送出完成後,會傳回送出的任務狀态,這個其實就是送出了一個http請求               
{      
   "node_name": "ZJPH-0321",      
   "status": "ok",      
   "jobid": "dd7f10aca76e11e99b656c4b90156b7e"      
}      
送出成功後,可以在浏覽器的job下面看到任務的執行情況

      
如果需要攜帶自定義的參數,那麼可以通過-d來指定,比如-d cc=scrapttest,和前面在本地執行時,增加自定義參數是一樣的。      
也可以通過http請求工具(比如soapui)送出一個http請求來觸發一個爬蟲任務

      
schedule.json請求中還可以包含如下參數      
setting (string, optional) –自定義爬蟲settings      
jobid (string, optional) –jobid,之前啟動過的spider,會有一個id,這個是可選參數      
_version (string, optional) –版本号,之前部署的時候的version,隻能使用int資料類型,沒指定,預設啟動最新版本      
8、 scrapyd 其他的API      
1)、curl http://localhost:6800/daemonstatus.json   檢查爬蟲服務的狀态      
2)、addversion.json增加項目到服務端  如果項目已經存在,則增加一個新的版本      
POST請求:      
project (string, required) –項目名      
version (string, required) –項目版本,不填寫則是目前時間戳      
egg (file, required) –目前項目的egg檔案      
curl http://localhost:6800/addversion.json -F project=myproject -F version=r23 -F [email protected]      
3)、  cancel.json      
取消一個 spdier的運作      
如果 spider是運作狀态,則停止其運作      
如果 spider是挂起狀态,則删除spider      
POST請求:      
project (string, required) –項目名      
job (string, required) -jobid      
curl http://localhost:6800/cancel.json -d project=myproject -d job=6487ec79947edab326d6db28a2d86511e8247444      
4)、listprojects.json      
擷取目前已上傳的項目的清單      
GET請求:      
curl http://localhost:6800/listprojects.json      
5)、listversions.json      
擷取指定項目的可用版本      
GET請求:      
project (string, required) –項目名      
curl http://localhost:6800/listversions.json?project=myproject      
6)、listspiders.json      
擷取指定版本的項目中的爬蟲清單,如果沒有指定版本,則是最新版本      
GET請求:      
project (string, required) –項目名      
_version (string, optional) –版本号      
$ curl http://localhost:6800/listspiders.json?project=myproject      
7)、 listjobs.json      
擷取指定項目中所有挂起、運作和運作結束的job      
GET請求      
project (string, option) - restrict results to project name      
curl http://localhost:6800/listjobs.json?project=myproject | python -m json.tool      
8)、delversion.json      
删除指定項目的指定版本      
POST請求      
project (string, required) - the project name      
version (string, required) - the project version      
curl http://localhost:6800/delversion.json -d project=myproject -d version=r99      
9)、delproject.json      
删除指定項目,并且包括所有的版本      
POST請求      
project (string, required) - the project name      
curl http://localhost:6800/delproject.json -d project=myproject        

 未完待續 第二篇

關于爬蟲平台的架構設計實作和架構的選型(二)--scrapy的内部實作以及實時爬蟲的實作 

 https://www.cnblogs.com/laoqing/p/11195324.html

作者的原創文章,轉載須注明出處。原創文章歸作者所有,歡迎轉載,但是保留版權。對于轉載了部落客的原創文章,不标注出處的,作者将依法追究版權,請尊重作者的成果。