python - scrapy 爬蟲框架(建立, 持久化, 去重, 深度, cookie)

## scrapy 依賴 twisted
  - twisted 是一個基於事件循環的 異步非阻塞 框架/模塊cookie

 

##  項目的建立  框架

1. 建立 project
    scrapy  startproject  項目名稱
   
    項目名稱(項目結構)
        - spiders    # 爬蟲文件
            - q.py
            - w.py
        - items.py         # 持久化
        - pipelines         # 持久化
        - middlewares.py   # 中間件
        - settings.py    # 配置文件(爬蟲)
    scrapy.cfg    # 配置文件(部署)

2. 建立爬蟲
    cd 項目名稱
   
    scrapy genspider  q  q.com
    scrapy genspider  w  w.com

3. 啓動爬蟲
    scrapy crawl  q --nolog   # 不查看日誌
    scrapy crawl  w              # 默認查看日誌

 

## pipeline 作持久化異步

    - pipeline 是全部爬蟲公用的,若是想要給某個爬蟲制定須要使用 spider 參數進行判斷處理:
      if spider.name == 'xxx'scrapy

1. 自定義的爬蟲文件中 將每次獲取到的數據 傳給 ScrapyDeom1Item 類方法
for item in item_list:
    href = item.xpath('.//a/@href').extract_first()
    txt = item.xpath('.//a/text()').extract_first()
    yield ScrapyDeom1Item(text=txt, href=href)

2. items 中 ScrapyDeom1Item 類方法 將須要存儲的數據接收到。
class ScrapyDeom1Item(scrapy.Item):
    href = scrapy.Field()
    text = scrapy.Field()

3. settings 中定義作持久化的類( ScrapyDeom1Pipeline ) 和 定義一個文件路徑
ITEM_PIPELINES = {
   'scrapy_deom1.pipelines.ScrapyDeom1Pipeline': 300,
       # 文件路徑                       # 優先級( 1-1000 )
}
PATH = 'new.log'

4. 到 pipelines.py 文件中 找到 ScrapyDeom1Pipeline 類並作持久化
from scrapy.exceptions import DropItem
class ScrapyDeom1Pipeline(object):

    def __init__(self, path):  # 初始化定義文件操做 和 文件要保存的路徑
        self.f = None
        self.path = path

    @classmethod
    def from_crawler(cls, crawler):
        """
        初始化的時候,用來建立 pipeline 對象
        :param crawler:
        :return:
        """
        # 去settings 尋找要保存的文件路徑
        path = crawler.settings.get('PATH')
        return cls(path)

    def open_spider(self, spider):
        """
        爬蟲剛啓動時調用 - 此處用來作打開文件操做
        :param spider:
        :return:
        """
        self.f = open(self.path, 'a+')

    def process_item(self, item, spider):
        """
        爬蟲執行中調用 - 此處用來作將數據寫入文件 操做
        :param item:
        :param spider:
        :return:
        """
        self.f.write(item['href']+'\n')
        # raise DropItem()   # 拋出異常,使後續的 pipeline 的 process_item 方法不執行
        return item    # 這個 item 是要返回給下個類的

    def close_spider(self, spider):
        """
        爬蟲執行完畢後調用 - 此處用來作關閉文件操做
        :param spider: 
        :return: 
        """
        self.f.close()

 

## 去重 ide

1. 建立一個 dupefilters.py 文件(用於作去重操做):
from scrapy.dupefilters import BaseDupeFilter
from scrapy.utils.request import request_fingerprint


class MyDupeFilter(BaseDupeFilter):

    def __init__(self):
        self.visited_fd = set()

    @classmethod
    def from_settings(cls, settings):
        return cls()

    def request_seen(self, request):
        """
        判斷當前請求的URL是否存在 - 用於去重
            - 若是存在則  pass
            - 如不存在則  添加
        :param request:
        :return:
        """
        # 將當前 URL 加密成必定位數的字符
        print(request)
        fd = request_fingerprint(request=request)
        if fd in self.visited_fd:
            return True
        self.visited_fd.add(fd)

    def open(self):  # can return deferred
        """
        執行前的一些操做
        :return:
        """
        print('爬蟲開始')

    def close(self, reason):  # can return a deferred
        """
        執行結束後的一些操做
        :param reason:
        :return:
        """
        print('爬蟲結束')

    def log(self, request, spider):  # log that a request has been filtered
        """
        訪問的每個  URL  的日誌信息
        :param request:
        :param spider:
        :return:
        """
        pass


2. settings 中註冊這個類
DUPEFILTER_CLASS = 'scrapy_demo1.dupefilters.MyDupeFilter'

3. 能夠設置是否使用當前定義的去重方法
# True 表示不使用 
# False 表示使用 (默認爲False)
yield Request(url=page, callback=self.parse, dont_filter=True)

 

##  限制深度查詢加密

配置文件中(settings):
DEPTH_LIMIT = 3  # 查詢深度設置爲三層

 

##  Cookieurl

# 解析 cookie
cookie_jar = CookieJar()
cookie_jar.extract_cookies(response, response.request)

# 去對象中將cookie解析到字典
for k, v in cookie_jar._cookies.items():
for i, j in v.items():
for m, n in j.items():
self.cookie_dict[m] = n.value

# 獲取 cookie

cookies=self.cookie_dict,
相關文章
相關標籤/搜索