一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

小白學(xué) Python 爬蟲(34):爬蟲框架 Scrapy 入門基礎(chǔ)(二)

 易禪浮屠 2022-03-04

人生苦短,我用 Python

前文傳送門:

小白學(xué) Python 爬蟲(1):開篇

小白學(xué) Python 爬蟲(2):前置準(zhǔn)備(一)基本類庫的安裝

小白學(xué) Python 爬蟲(3):前置準(zhǔn)備(二)Linux基礎(chǔ)入門

小白學(xué) Python 爬蟲(4):前置準(zhǔn)備(三)Docker基礎(chǔ)入門

小白學(xué) Python 爬蟲(5):前置準(zhǔn)備(四)數(shù)據(jù)庫基礎(chǔ)

小白學(xué) Python 爬蟲(6):前置準(zhǔn)備(五)爬蟲框架的安裝

小白學(xué) Python 爬蟲(7):HTTP 基礎(chǔ)

小白學(xué) Python 爬蟲(8):網(wǎng)頁基礎(chǔ)

小白學(xué) Python 爬蟲(9):爬蟲基礎(chǔ)

小白學(xué) Python 爬蟲(10):Session 和 Cookies

小白學(xué) Python 爬蟲(11):urllib 基礎(chǔ)使用(一)

小白學(xué) Python 爬蟲(12):urllib 基礎(chǔ)使用(二)

小白學(xué) Python 爬蟲(13):urllib 基礎(chǔ)使用(三)

小白學(xué) Python 爬蟲(14):urllib 基礎(chǔ)使用(四)

小白學(xué) Python 爬蟲(15):urllib 基礎(chǔ)使用(五)

小白學(xué) Python 爬蟲(16):urllib 實(shí)戰(zhàn)之爬取妹子圖

小白學(xué) Python 爬蟲(17):Requests 基礎(chǔ)使用

小白學(xué) Python 爬蟲(18):Requests 進(jìn)階操作

小白學(xué) Python 爬蟲(19):Xpath 基操

小白學(xué) Python 爬蟲(20):Xpath 進(jìn)階

小白學(xué) Python 爬蟲(21):解析庫 Beautiful Soup(上)

小白學(xué) Python 爬蟲(22):解析庫 Beautiful Soup(下)

小白學(xué) Python 爬蟲(23):解析庫 pyquery 入門

小白學(xué) Python 爬蟲(24):2019 豆瓣電影排行

小白學(xué) Python 爬蟲(25):爬取股票信息

小白學(xué) Python 爬蟲(26):為啥買不起上海二手房你都買不起

小白學(xué) Python 爬蟲(27):自動(dòng)化測試框架 Selenium 從入門到放棄(上)

小白學(xué) Python 爬蟲(28):自動(dòng)化測試框架 Selenium 從入門到放棄(下)

小白學(xué) Python 爬蟲(29):Selenium 獲取某大型電商網(wǎng)站商品信息

小白學(xué) Python 爬蟲(30):代理基礎(chǔ)

小白學(xué) Python 爬蟲(31):自己構(gòu)建一個(gè)簡單的代理池

小白學(xué) Python 爬蟲(32):異步請求庫 AIOHTTP 基礎(chǔ)入門

小白學(xué) Python 爬蟲(33):爬蟲框架 Scrapy 入門基礎(chǔ)(一)

引言

在上一篇文章 小白學(xué) Python 爬蟲(33):爬蟲框架 Scrapy 入門基礎(chǔ)(一) 中,我們簡單的使用了 Spider 抓取到了我們需要的信息,我們簡單的將我所需要的信息通過 print() 的方式打印了在了控制臺(tái)上。

在我們實(shí)際使用爬蟲的過程中,我們更多的是需要將數(shù)據(jù)保存起來,并不是直接輸出至控制臺(tái),本篇文章接著講我們?nèi)绾螌?Spider 抓取到的信息保存起來。

Item

Item 的主要目的是從非結(jié)構(gòu)化源(通常是網(wǎng)頁)中提取結(jié)構(gòu)化數(shù)據(jù)。

Scrapy Spider可以將提取的數(shù)據(jù)作為Python字典返回。Python字典雖然方便且熟悉,但缺乏結(jié)構(gòu):很容易在字段名稱中輸入錯(cuò)誤或返回不一致的數(shù)據(jù),尤其是在具有許多蜘蛛的大型項(xiàng)目中。

為了定義常見的輸出數(shù)據(jù)格式, Scrapy 提供了 Item 該類。 Item 對象是用于收集抓取數(shù)據(jù)的簡單容器。它們提供了類似于字典的 API ,具有方便的語法來聲明其可用字段。

接下來,我們來創(chuàng)建一個(gè) Item 。

創(chuàng)建 Item 需要繼承 scrapy.Item 類,并且定義類型為 scrapy.Field 的字段。

在前面一篇文章中,我們的目的想要獲取的字段有 text 、 author 、 tags 。

那么,我們定義的 Item 類如下,這里直接修改 items.py 文件:

import scrapy

class QuoteItem(scrapy.Item):
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()

接下來就是我們?nèi)绾我?first_scrapy 項(xiàng)目中使用這個(gè) Item 了,修改之前的 QuotesSpider 如下:

import scrapy
from first_scrapy.items import QuoteItem

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    allowed_domains = ['quotes.']
    start_urls = ['http://quotes./']

    def parse(self, response):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract()
            yield item

接下來,我們可以通過最簡單的命令行將我們剛才獲取到的數(shù)據(jù)保存為 json 文件,命令如下:

scrapy crawl quotes -o quotes.json

執(zhí)行后可以看到在當(dāng)前目錄下生成了一個(gè)名為 quotes.json 的文件,具體內(nèi)容如下:

輸出格式還支持很多種,例如 csv、xml、pickle、marshal 等,常見的輸出語句如下:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal

直到這里,我們簡單的將獲取到的數(shù)據(jù)導(dǎo)出成了 json 文件,這就結(jié)束了么?

當(dāng)然沒有,前一篇文章我們只是簡單的獲取了當(dāng)前頁面的內(nèi)容,如果我們想抓取后續(xù)頁面的內(nèi)容怎么做呢?

當(dāng)然,第一步我們需要先觀察后面一頁的鏈接:http://quotes./page/2 。

接下來,我們需要構(gòu)造一個(gè)訪問下一頁的請求,這時(shí)我們可以使用 scrapy.Request 。

這里我們使用 Request() 先簡單的傳入兩個(gè)參數(shù),實(shí)際上可以傳入的參數(shù)遠(yuǎn)不止兩個(gè),這個(gè)我們后面再聊。

  • url:此請求的URL

  • callback:它是回調(diào)函數(shù)。當(dāng)指定了該回調(diào)函數(shù)的請求完成之后,獲取到響應(yīng),引擎會(huì)將該響應(yīng)作為參數(shù)傳遞給這個(gè)回調(diào)函數(shù)。

那么接下來我們要做的就是使用選擇器得到下一頁鏈接并生成請求,使用 scrapy.Request 訪問此鏈接,進(jìn)行新一輪的數(shù)據(jù)抓取。

添加的代碼如下:

next = response.css('.pager .next a::attr("href")').extract_first()
url = response.urljoin(next)
yield scrapy.Request(url=url, callback=self.parse)

現(xiàn)在,改動(dòng)后的 Spider 類整體代碼如下:

# -*- coding: utf-8 -*-
import scrapy
from first_scrapy.items import QuoteItem

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    allowed_domains = ['quotes.']
    start_urls = ['http://quotes./']

    def parse(self, response):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract()
            yield item

        next = response.css('.pager .next a::attr("href")').extract_first()
        url = response.urljoin(next)
        yield scrapy.Request(url=url, callback=self.parse)

再次使用命令執(zhí)行這個(gè) Spider ,得到的結(jié)果如下(注意,如果前面生成過 json 文件,記得刪除后再運(yùn)行,否則會(huì)直接追加寫):

可以看到,數(shù)據(jù)增加了許多,說明我們抓取后續(xù)頁面的數(shù)據(jù)成功。

到這里就結(jié)束了么?怎么可能,我們這里只是簡單的將數(shù)據(jù)保存在了 json 文件中,并不方便我們的取用,這里我們可以將數(shù)據(jù)保存在我們所需要的數(shù)據(jù)庫中。

Item Pipeline

當(dāng)我們想將數(shù)據(jù)保存在數(shù)據(jù)庫中時(shí),可以使用 Item Pipeline ,Item Pipeline 為項(xiàng)目管道。

這個(gè)管道的典型用途有:

  • 清洗 HTML 數(shù)據(jù)

  • 驗(yàn)證爬取數(shù)據(jù),檢查爬取字段

  • 查重并丟棄重復(fù)內(nèi)容

  • 將爬取結(jié)果儲(chǔ)存到數(shù)據(jù)庫

本示例選擇保存的數(shù)據(jù)為 MongoDB ,接下來,我們會(huì)將前面查詢出來的數(shù)據(jù)保存在 MongoDB 中。

emmmmmmmmmm,如果要問小編 MongoDB 怎么安裝的話,簡單來講,直接使用 Docker 進(jìn)行安裝,只需幾個(gè)簡單的命令即可:

docker pull mongo (拉取鏡像 默認(rèn)最新版本)

docker images (查看鏡像)

docker run -p 27017:27017 -td mongo (啟動(dòng)鏡像)

docker ps (查看啟動(dòng)的鏡像)

如果不出意外,以上這幾句話執(zhí)行一下就可以了。連接工具可以使用 Navicat 。

這里我們直接修改 pipelines.py 文件,之前使用命令自動(dòng)生成的內(nèi)容可以全都刪掉,寫入以下內(nèi)容:

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

from scrapy.exceptions import DropItem

class TextPipeline(object):

    def process_item(self, item, spider):
        if item['text']:
            return item
        else:
            return DropItem('Missing Text')

這里我們實(shí)現(xiàn)了 process_item() 方法,其參數(shù)是 item 和 spider。

這里簡單判斷了當(dāng)前的 text 是否存在,如果不存在則直接拋出 DropItem 異常,如果存在則直接返回 item 。

接下來,我們將處理后的 item 存入 MongoDB,定義另外一個(gè) Pipeline。同樣在 pipelines.py 中,我們實(shí)現(xiàn)另一個(gè)類 MongoPipeline,內(nèi)容如下所示:

import pymongo

class MongoPipeline(object):
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        return cls(mongo_uri=crawler.settings.get('MONGO_URI'),
                   mongo_db=crawler.settings.get('MONGO_DB')
                   )

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def process_item(self, item, spider):
        name = item.__class__.__name__
        self.db[name].insert(dict(item))
        return item

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

MongoPipeline 類實(shí)現(xiàn)了 API 定義的另外幾個(gè)方法。

  • from_crawler,這是一個(gè)類方法,用 @classmethod 標(biāo)識(shí),是一種依賴注入的方式,方法的參數(shù)就是 crawler,通過 crawler 這個(gè)我們可以拿到全局配置的每個(gè)配置信息,在全局配置 settings.py 中我們可以定義 MONGO_URI 和 MONGO_DB 來指定 MongoDB 連接需要的地址和數(shù)據(jù)庫名稱,拿到配置信息之后返回類對象即可。所以這個(gè)方法的定義主要是用來獲取 settings.py 中的配置的。

  • open_spider,當(dāng) Spider 被開啟時(shí),這個(gè)方法被調(diào)用。在這里主要進(jìn)行了一些初始化操作。

  • close_spider,當(dāng) Spider 被關(guān)閉時(shí),這個(gè)方法會(huì)調(diào)用,在這里將數(shù)據(jù)庫連接關(guān)閉。
    最主要的 process_item() 方法則執(zhí)行了數(shù)據(jù)插入操作。

定義好 TextPipeline 和 MongoPipeline 這兩個(gè)類后,我們需要在 settings.py 中使用它們。MongoDB 的連接信息還需要定義。

在 settings.py 中加入如下內(nèi)容:

ITEM_PIPELINES = {
    'first_scrapy.pipelines.TextPipeline': 300,
    'first_scrapy.pipelines.MongoPipeline': 400,
}
MONGO_URI='localhost'
MONGO_DB='first_scrapy'

再次執(zhí)行爬取命令:

scrapy crawl quotes

執(zhí)行結(jié)果如下:

可以看到,在 MongoDB 中創(chuàng)建了一個(gè) QuoteItem 的表,表中保存了我們剛才抓取到的數(shù)據(jù)。

示例代碼

本系列的所有代碼小編都會(huì)放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。

示例代碼-Github

示例代碼-Gitee

參考

https://docs./en/latest/topics/request-response.html

https://docs./en/latest/topics/items.html

https:///8337.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    成人综合网视频在线观看| 国产福利一区二区久久| 国产精品日韩欧美一区二区| 国产一级二级三级观看| 中日韩美女黄色一级片| 91欧美日韩国产在线观看| 在线亚洲成人中文字幕高清| 国产日韩欧美在线播放| 黄色国产自拍在线观看| 丰满人妻一二三区av| 亚洲精品福利视频在线观看| 久久精品亚洲精品一区| 国产欧美日韩一级小黄片| 国产日韩欧美在线亚洲| 日韩人妻中文字幕精品| 日本精品中文字幕在线视频| 日韩人妻毛片中文字幕| 欧美精品一区二区三区白虎| 亚洲中文字幕在线观看黑人| 国产精品亚洲二区三区| 欧美色婷婷综合狠狠爱| 欧美成人免费夜夜黄啪啪| 日韩av亚洲一区二区三区| 亚洲精品国产美女久久久99| 日本丁香婷婷欧美激情| 欧美成人国产精品高清| 亚洲最新的黄色录像在线| 加勒比东京热拍拍一区二区| 中文字幕一二区在线观看| 国产综合欧美日韩在线精品| 91亚洲国产成人久久| 欧美日韩国产一级91| 91麻豆精品欧美一区| 国产欧美日韩综合精品二区| 在线观看中文字幕91| 老富婆找帅哥按摩抠逼视频| 精品少妇人妻一区二区三区| 91人妻人人澡人人人人精品| 中文字日产幕码三区国产| 香蕉尹人视频在线精品| 国产无摭挡又爽又色又刺激|