1. 程式人生 > >Python3 爬蟲之 Scrapy 快速入門

Python3 爬蟲之 Scrapy 快速入門

初識 Scrapy

Scrapy 是一個為了爬取網站資料,提取結構性資料而編寫的應用框架。 可以應用在包括資料探勘,資訊處理或儲存歷史資料等一系列的程式中。其最初是為了頁面抓取(更確切來說, 網路抓取)所設計的, 也可以應用在獲取API所返回的資料(例如 Amazon Associates Web Services)或者通用的網路爬蟲。

Scrapy 環境搭建

1. 安裝 Python 3.6,本文使用 Python 3.6,且在 PATH 中設定好環境變數。推薦使用Anaconda3 (https://www.anaconda.com/download/

2. 安裝 Scrapy-1.5.1,通過 pip 安裝 Scrapy:pip install Scrapy

3. 可能還需的包,包括涉及資料庫儲存操作的pymssql (適用於sql server):pip install pymssql 

Scrapy 專案建立

開啟命令列視窗,新建一個 scrapy 工程:

scrapy startproject SpiderProjectName(專案名稱)

這個命令會在當前目錄(根據需求設定)下建立一個新目錄 SpiderProjectName,這就是此爬蟲的專案名稱。

成功建立爬蟲專案檔案結構後,進入目錄,使用命令: tree /f  檢視檔案層級的結構關係

這些檔案主要是:
scrapy.cfg: 專案配置檔案
SpiderProjectName/: 專案python模組, 程式碼將從這裡匯入
SpiderProjectName/items.py: 專案items檔案
SpiderProjectName/pipelines.py: 專案管道檔案
SpiderProjectName/settings.py: 專案配置檔案
SpiderProjectName/spiders: 放置spider的目錄

定義item

編輯 items.py 檔案,items 是將要裝載抓取的資料的容器,它工作方式像 python 裡面的字典,但它提供更多的保護,比如對未定義的欄位填充以防止拼寫錯誤。在 items.py 檔案裡,scrapy 需要我們定義一個容器用於放置爬蟲抓取的資料,它通過建立一個scrapy.Item 類來宣告,定義它的屬性為scrpy.Field 物件,就像是一個物件關係對映(ORM, Object Relational Mapping)。我們通過將需要的 item 模型化,來控制從站點獲得的新聞資料,比如我們要獲得新聞的標題項、內容項、發表時間、圖片連結地址和頁面連結地址,則定義這5種屬性的域。Scrapy 框架已經定義好了基礎的 item,我們自己的 item 只需繼承 scrapy.Item 即可。

# 示例
class ClawlerItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 主題名稱
    title = scrapy.Field()
    # 主題種類
    category = scrapy.Field()
    # 語言
    lang = scrapy.Field()
    # 返回內容
    content = scrapy.Field()
    pass

爬蟲spider主程式

在spiders資料夾下,新建 SpiderName.py 檔案, Scrapy 框架已經幫助我們定義好了基礎爬蟲,只需要從 scrapy.spider 繼承,並重寫相應的解析函式 parse 即可。其中會涉及到使用 xPath 獲取頁面元素路徑的操作,xPaht 是 XML 頁面路徑語言,使用路徑表示式來選取 XML 文件中的節點或節點集,節點是通過沿著路徑(Path)或者步(Steps)來選取的,html 是 XML 的子集,當然同樣適用,有興趣的讀者可以自行查閱相關的 Xpath 文件。

資料儲存

編輯 pipelines.py 檔案,用於將 items 中的資料儲存到資料庫或者本地文字等。

# 涉及資料庫儲存的方式,資料庫引數都在settings中設定,更靈活
import pymssql
class ClawlerPipeline(object):
    # 定義資料庫連結
    def __init__(self):
        self.connect = pymssql.connect(host=SQLServer_HOST, user=SQLServer_USER, password=SQLServer_PASSWD,
                                    database=SQLServer_DBNAME, port=SQLServer_PORT)
        self.cursor = self.connect.cursor()

    def process_item(self, item, spider):
        try:
            sql = "insert into dbo.YB_ALL(ztid,title,category,lang,content,gxrq,demo) values (%s,%s,%s,%s,%s,%s,%s)"
            self.cursor.execute(sql,(item['id'],item['title'], item['category'], item['lang'], str(item['content']), timestamp, None))
            self.connect.commit()
            time.sleep(10)
            self.close_spider(spider)
        except Exception as error:
            get_logger('error.log').info(str(error))

    def close_spider(self, spider):
        self.connect.close()

    # 本地儲存方式
    # def process_item(self, item, spider):
    #     with open("test1.txt", 'a', encoding='utf-8') as fw:
    #         # json.dump(str(item['content']), fw, ensure_ascii=False)
    #         fw.write(str(item['content']) + '\n')
# util.py工具類中的日誌方法也貼出來分享吧

import logging

def get_logger(filename):
    logger = logging.getLogger('logger')
    logger.setLevel(logging.DEBUG)
    logging.basicConfig(format='%(message)s', level=logging.DEBUG)
    handler = logging.FileHandler(filename)
    handler.setLevel(logging.DEBUG)
    handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
    logging.getLogger().addHandler(handler)
    return logger

啟用 pipeline 管道

編輯 settings.py 檔案 中的 ITEM_PIPELINES ,新增如下程式碼

# DBspiderPipeline 是你定義在Pipeline檔案中的類
# 專案名.pipelines.管道類名, 根據你的情況更改
ITEM_PIPELINES = {
    'SpiderProjectName.pipelines.DBSpiderPipeline': 300,
}

# 編碼
FEED_EXPORT_ENCODING = 'utf-8'

# 資料庫宣告
SQLServer_HOST = '127.0.0.1'
SQLServer_DBNAME = 'DATA_SAMPLE'
SQLServer_USER = 'sa'
SQLServer_PASSWD = '12345'
SQLServer_PORT = 1433

包括資料庫屬性,編碼等等,都可以在settings.py中設定

執行爬蟲

爬蟲專案根目錄下,執行命令如下:

scrapy crawl SpiderProjectName