爬蟲框架Scrapy體驗

填坑計劃:scrapy

scrapy簡介

Scrapy是適用於Python的一個快速、高層次的屏幕抓取和web抓取框架,用於抓取web站點並從頁面中提取結構化的數據。Scrapy用途廣泛,可以用於數據挖掘、監測和自動化測試。

Scrapy吸引人的地方在於它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種類型爬蟲的基類,如BaseSpider、sitemap爬蟲等,最新版本又提供了web2.0爬蟲的支持。

ScrapyDemo

  1. 安裝scrapy

    pip3 install scrapy
    
  2. 創建scrapy項目
    在項目目錄下:

    scrapy startproject ScrapyDemo
    
  3. 使用PyCharm打開項目
    爲了操作方便,在項目根目錄下創建run.py,以用於後面的啓動和調試項目

    # -*- coding: utf-8 -*-
    # 啓動項目腳本
    
    from scrapy.cmdline import execute
    
    # 創建爬蟲
    execute('scrapy genspider qidian_bookinfo "book.qidian.com"'.split())
    

    可以看到:使用scrapy.cmdline.execute方法執行命令行指令,需要使用split函數將指令分隔開

  4. 創建爬蟲
    在項目目錄下執行指令

    scrapy genspider qidian_bookinfo "book.qidian.com"
    

    創建一個爬蟲,爬取的範圍是起點小說網的book目錄,本次就先拿這個作爲實驗對象

  5. 創建item對象
    在Items.py文件中,按照提示創建內容
    我們計劃爬取某小說的題目、作者、宣傳語、簡介內容四個部分,因此要創建4個Item

    import scrapy
    class ScrapydemoItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        title = scrapy.Field()
        author = scrapy.Field()
        intro = scrapy.Field()
        entry = scrapy.Field()
    
  6. 編寫爬蟲文件qidian_bookinfo.py

    # -*- coding: utf-8 -*-
    import scrapy
    from ScrapyDemo.items import ScrapydemoItem
    # 具體爬蟲文件
    
    class QidianBookinfoSpider(scrapy.Spider):
        name = 'qidian_bookinfo'
        # 允許爬取的域名範圍
        allowed_domains = ['book.qidian.com'] 
        # 開始爬取url
        start_urls = ['https://book.qidian.com/info/1004990267/']
    
        def parse(self, response):
            title = response.xpath('//div[@class="book-info "]//h1//em/text()').get()
            author = response.xpath('//div[@class="book-info "]//h1//span//a/text()').get()
            intro = response.xpath('//div[@class="book-info "]//p[@class="intro"]/text()').get()
            entry = response.xpath('//div[@class="book-intro"]//p/text()').get().strip()
            # 返回對象
            item = ScrapydemoItem(title=title, author=author, intro=intro, entry=entry)
            # 生成item
            yield item
    

    可以看到,這裏使用的xpath作爲選擇器,因此需要先了解xpath語法
    xpath語法參考
    其實理解起來比較容易,比如下面的xpath解析式:

    //div[@class="book-info "]//h1//em/text()
    

    解析的對象是class="book-info "的div的下面的h1,h1下面的em標籤中的文本內容,這個內容就是作品題目

    注意: 這裏作者遇到了一個坑點(和程序無關),這個網站的info頁面book-info類的div標籤類是帶一個空格的,筆者一開始去掉了空格,結果什麼都爬不到、

    [@class="book-info "] #字符串最後有個空格是故意加上的,不加空格爬取不到
    
  7. 使用pipline處理內容
    在pipline.py文件中處理爬蟲返回的內容,這裏將獲得的四種信息轉換成json格式並且存儲到本地文件
    使用了scrapy中專門輸出Json格式數據的JsonLinesItemExporter來輸出數據

from scrapy.exporters import JsonLinesItemExporter

class ScrapydemoPipeline:

    def __init__(self):
        self.fp = open("bookinfo.json", "wb")
        # json文件輸出器
        self.exporter = JsonLinesItemExporter(self.fp, ensure_ascii=False, encoding='utf-8')

    def open_spider(self, spider):
        self.exporter.start_exporting()

    def process_item(self, item, spider):
        self.exporter.export_item(item)
        return item

    def close_spider(self, spider):
        self.fp.close()
        self.exporter.finish_exporting()
        print("結束")
  1. 配置settings.py
    在我們寫好了所有內容之後,爬蟲需要進行配置才能運行
    編輯settings.py,取消註釋並且配置一下內容:
    # 1. 關閉遵守robots協議
    ROBOTSTXT_OBEY = False
    
    # 2. 僞裝身份
    DEFAULT_REQUEST_HEADERS = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'
    }
    
    # 3. 使用pipeline處理獲取數據
    ITEM_PIPELINES = {
       'ScrapyDemo.pipelines.ScrapydemoPipeline': 300,
    }
    
  2. 在run.py中運行如下內容,即可啓動爬蟲
    #執行指令
    execute('scrapy crawl qidian_bookinfo'.split())
    
  3. 檢查目錄下的bookinfo.json結果
    {
    	"title": "穿越之皇帝成長計劃",
    	"author": "奧特曼會寫字",
    	"intro": "醒掌天下權,醉臥美人膝,五千年風華煙雨,是非成敗轉頭空!",
    	"entry": "主角一朝穿越驚現成了即將登位的太子,治理自己的國家。尋找名妃,培養子女,爾虞我詐;發展國家,收錄名臣,秣馬厲兵。是後宮佳麗三千還是後宮佳麗三千;西楚霸王、蜀漢名將、水滸英雄,誰能助我一統天下;從三皇五帝到唐宗宋祖,雄霸天下亦或是兒女情長,收錄不盡的名臣美人,挑戰無限的激情國戰。"
    }
    
    使用JsonLinesItemExporter輸出的數據如果有多個會佔多行,每行是獨立的json數據
    如果使用JsonItemExporter輸出數據,多行數據是裝在一個json列表裏的,只佔一行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章