第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Scrapy 入門教程 Scrapy 入門教程 Scrapy 框架的 Shell 工具使用

Scrapy 框架的 Shell 工具使用

今天我們來介紹和實戰(zhàn) Scrapy 框架的命令行模式,它和 Django 框架的 shell 模式一樣,用于我們前期調(diào)試工程代碼,非常方便,掌握好 Scrapy 的 shell 模式會使得我們開發(fā)爬蟲更為順暢。

1. Scrapy Shell 介紹

Scrapy Shell 一個交互終端,類似于 Python 交互式模式,它使我們可以在未啟動 Scrapy 爬蟲的情況下調(diào)試爬蟲代碼。

在 Scrapy 的交互模式下,我們可以直接獲取網(wǎng)頁的 Response 結(jié)果,然后使用 XPath 或 CSS 表達式來獲取網(wǎng)頁元素,并以此測試我們獲取網(wǎng)頁數(shù)據(jù)的 Xpath 或者 CSS 表達式,確保后續(xù)執(zhí)行時能正確得到數(shù)據(jù)。我們來看看如何進入 shell 模式,參考如下的視頻:

在 Scrapy 框架中內(nèi)置了 Selector 選擇器,這個選擇器是屬于 parsel 模塊的,而 parsel 模塊是由 Scrapy 團隊為解析網(wǎng)頁而開發(fā)的,并且獨立出來形成了一個第三方模塊。

這樣我們可以在自己的爬蟲程序中使用 parsel 模塊而不必基于 Scrapy 框架 。我們從源碼中來看看這個選擇器類的定義??梢钥吹?Selector 類有我們熟悉的 xpath()css()、re() 以及 extract() 等方法,這些是我們解析網(wǎng)頁的基礎(chǔ)。

圖片描述

Selector 類方法

我們來思考一個問題,然后去源碼中找到答案:

(scrapy-test) [root@server ~]# scrapy shell https://gz.lianjia.com/ershoufang/ --nolog
...
>>> type(response)
<class 'scrapy.http.response.html.HtmlResponse'>

我們在 Scrapy Shell 中可以看到 response 是 HtmlResponse 的一個實例,它是怎么會有 Selector 的方法的?我們在前面的 Scrapy 初步的實例中看到過 response.xpath() 這樣的用法,源碼里面是怎么做的呢?

這個問題比較簡單,我們翻看一下源碼就可以找到答案了。首先查看 HtmlResponse 類定義:

# 源碼位置:scrapy/http/response/html.py
from scrapy.http.response.text import TextResponse

class HtmlResponse(TextResponse):
    pass

這個夠不夠簡單?繼續(xù)追看 TextResponse 的定義:

# 源碼位置:scrapy/http/response/text.py
# ...

class TextResponse(Response):
    # ...
    
    @property
    def selector(self):
        from scrapy.selector import Selector
        if self._cached_selector is None:
            self._cached_selector = Selector(self)
        return self._cached_selector
    
    # ...
    
    def xpath(self, query, **kwargs):
        return self.selector.xpath(query, **kwargs)

    def css(self, query):
        return self.selector.css(query)
    
    # ...

是不是一下子就明白了?response.xpath() 正是調(diào)用的 scrapy.selector 下的Selector,繼續(xù)看這個 Selector 的定義:

# 源碼位置:scrapy/selector/unified.py

from parsel import Selector as _ParselSelector

class Selector(_ParselSelector, object_ref):
    # ...

是不是最后又到了 parsel 下的 Selector?所以使用 response.xpath() 等價于使用 parsel 模塊 下的 Selector 類中的 xpath 方法去定位網(wǎng)頁元素。在給大家留一個更進一步的問題:

在前面爬取互動出版網(wǎng)的 Scrapy 框架實例中,我們還用到了這樣的表達式:book.xpath().extract()[0]book.xpath().extract_first(),這樣的代碼執(zhí)行過程又是怎樣的呢(追蹤到 parsel 這一層即可)?

這個問題追蹤的代碼會比上面多一點,但也不復(fù)雜,這個問題會在下一節(jié)的 Reponse 類分析中給出相應(yīng)的回答。

2. Scrapy Shell 實戰(zhàn)

上面介紹了一些 Scrapy Shell 和 Response 的基礎(chǔ)知識,我們現(xiàn)在就來在 Scrapy Shell 中實戰(zhàn) Selector 選擇器。本次測試的網(wǎng)站為廣州鏈家,測試頁面為二手房頁面:

圖片描述

鏈家二手房網(wǎng)站

我已經(jīng)在上面標出了想要爬取的網(wǎng)頁信息,后面也主要測試這些數(shù)據(jù)的 xpath 表達式 或者 css 表達式。首先使用 scrapy shell 目標網(wǎng)址 命令進行想要的命令行,此時 Scrapy 框架已經(jīng)為我們將目標網(wǎng)站的網(wǎng)頁數(shù)據(jù)爬取了下來:

(scrapy-test) [root@server ~]# scrapy shell https://gz.lianjia.com/ershoufang/
...
>>> response
<200 https://gz.lianjia.com/ershoufang/>

我們看到響應(yīng)的網(wǎng)頁數(shù)據(jù)已經(jīng)有了,接下來我們就可以開始進行網(wǎng)頁分析來抓取圖片中標記的數(shù)據(jù)了。首先是標題信息:
圖片描述

提取二手房數(shù)據(jù)的標題信息

根據(jù)上面的網(wǎng)頁結(jié)構(gòu),可以很快得到標題的 xpath 路徑表達式:

標題://ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()

在 Scrapy Shell 中我們實戰(zhàn)一把:

>>> response.xpath('//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()')
[<Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='地鐵口  總價低  精裝實用小兩房'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='剛需精裝小三房/三房兩廳一廚一衛(wèi)/廣州東綠湖國際城'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='周門社區(qū) 綠雅苑六樓 精裝三房'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='金碧領(lǐng)秀國際 精裝修一房 中樓層采光好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='戶型方正 采光好 通風透氣 小區(qū)安靜'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='毛紡小區(qū) 南向兩房 方正實用 采光好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='南奧疊層復(fù)式  前后樓距開闊  南北對流通風好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='丹桂園 實用三房精裝修 南向戶型 擰包入住'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='周門小區(qū)大院管理 近地鐵總價低全明正規(guī)一房一廳'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='云鶴北街 精裝低樓層 南向兩房'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='中海譽城東南向兩房,住家安靜,無抵押交易快'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='精裝兩房,步梯中層,總價低,交通方便,配套齊全'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='中層南向四房 格局方正 樓層適中'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='精裝修 戶型好 中空一房 采光保養(yǎng)很好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='業(yè)主急售,價格優(yōu)質(zhì)看房方便有密碼'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='匯僑新城北區(qū) 精裝三房 看花園 戶型靚'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='小區(qū)中間,安靜,前無遮擋,視野寬闊,望別墅花園'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='小區(qū)側(cè)邊位 通風采光好 小區(qū)管理 裝修保養(yǎng)好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='萬科三房   南北對流    中高層采光好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='南北對流,采光充足,配套設(shè)施完善,交通便利'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='美力倚睛居3房南有精裝修拎包入住'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='美心翠擁華庭二期 3室2廳 228萬'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='天河公園門口 交通便利 配套成熟'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='保利香檳花園 高層視野好 保養(yǎng)很好 居家感好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='恒安大廈兩房,有公交,交通方便,價格方面可談'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='此房是商品房,低層,南北對流,全明屋'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='水蔭直街 原裝電梯戶型 方正三房格局'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='嘉誠國際公寓 可明火 正規(guī)一房一廳'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='近地鐵兩房  均價低  業(yè)主自住 裝修保養(yǎng)好'>, <Selector xpath='//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()' data='宏城匯 三房 南向 采光好 戶型方正 交通便利'>]

上面結(jié)果返回的是 SelectorList 類型:

>>> data_list = response.xpath('//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()')
>>> type(data_list)
<class 'scrapy.selector.unified.SelectorList'>

最后我們通過提取 Selector 的 root 屬性,只得到相應(yīng)的文本信息:

>>> data = [d.root for d in data_list]
>>> data
['地鐵口  總價低  精裝實用小兩房', '剛需精裝小三房/三房兩廳一廚一衛(wèi)/廣州東綠湖國際城', '周門社區(qū) 綠雅苑六樓 精裝三房', '金碧領(lǐng)秀國際 精裝修一房 中樓層采光好', '戶型方正 采光好 通風透氣 小區(qū)安靜', '毛紡小區(qū) 南向兩房 方正實用 采光好', '南奧疊層復(fù)式  前后樓距開闊  南北對流通風好', '丹桂園 實用三房精裝修 南向戶型 擰包入住', '周門小區(qū)大院管理 近地鐵總價低全明正規(guī)一房一廳', '云鶴北街 精裝低樓層 南向兩房', '中海譽城東南向兩房,住家安靜,無抵押交易快', '精裝兩房,步梯中層,總價低,交通方便,配套齊全', '中層南向四房 格局方正 樓層適中', '精裝修 戶型好 中空一房 采光保養(yǎng)很好', '業(yè)主急售,價格優(yōu)質(zhì)看房方便有密碼', '匯僑新城北區(qū) 精裝三房 看花園 戶型靚', '小區(qū)中間,安靜,前無遮擋,視野寬闊,望別墅花園', '小區(qū)側(cè)邊位 通風采光好 小區(qū)管理 裝修保養(yǎng)好', '萬科三房   南北對流    中高層采光好', '南北對流,采光充足,配套設(shè)施完善,交通便利', '美力倚睛居3房南有精裝修拎包入住', '美心翠擁華庭二期 3室2廳 228萬', '天河公園門口 交通便利 配套成熟', '保利香檳花園 高層視野好 保養(yǎng)很好 居家感好', '恒安大廈兩房,有公交,交通方便,價格方面可談', '此房是商品房,低層,南北對流,全明屋', '水蔭直街 原裝電梯戶型 方正三房格局', '嘉誠國際公寓 可明火 正規(guī)一房一廳', '近地鐵兩房  均價低  業(yè)主自住 裝修保養(yǎng)好', '宏城匯 三房 南向 采光好 戶型方正 交通便利']

是不是非常簡單就爬到了數(shù)據(jù)?另外,我們還可以使用 extract()[0] 或者 extract_first() 這樣的方式來提取結(jié)果列表中的第一個文本數(shù)據(jù):

>>> data = response.xpath('//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()').extract()[0]
>>> data2 = response.xpath('//ul[@class="sellListContent"]/li/div/div[@class="title"]/a/text()').extract_first()
>>> data == data2
True
>>> data
'地鐵口  總價低  精裝實用小兩房'

接下來,我們依次找出獲取二手房位置、房屋價格、房屋信息的 xpath 路徑表達式:

房屋位置:
//ul[@class="sellListContent"]/li/div/div[@class="food"]/div[@class="positionInfo"]/a[]/text()
房屋信息:
//ul[@class="sellListContent"]/li/div/div[@class="address"]/div[@class="houseInfo"]/text()
房屋價格:
//ul[@class="sellListContent"]/li/div/div[@class="priceInfo"]/div[@class="totalPrice"]/span/text()

有了這些之后,我們就可以依次提取出二手房的【標題介紹】、【房屋位置】、【房屋信息】以及【房屋價格】這些信息。此外對于提取的【房屋信息】字段還要進一步處理,分割成【房屋結(jié)構(gòu)】、【房屋大小】以及【朝向】等信息。這些信息將在 Spider 模塊中進行提取,也就是我們前面互動出版網(wǎng)爬蟲的 ChinaPubCrawler.py 文件中的 ChinaPubCrawler 類來解析。

最后我們在介紹下 scrapy shell 命令的參數(shù):

(scrapy-test) [root@server ~]# scrapy shell --help
Usage
=====
  scrapy shell [url|file]

Interactive console for scraping the given url or file. Use ./file.html syntax
or full path for local file.

Options
=======
--help, -h              show this help message and exit
-c CODE                 evaluate the code in the shell, print the result and
                        exit
--spider=SPIDER         use this spider
--no-redirect           do not handle HTTP 3xx status codes and print response
                        as-is

Global Options
--------------
--logfile=FILE          log file. if omitted stderr will be used
--loglevel=LEVEL, -L LEVEL
                        log level (default: DEBUG)
--nolog                 disable logging completely
--profile=FILE          write python cProfile stats to FILE
--pidfile=FILE          write process ID to FILE
--set=NAME=VALUE, -s NAME=VALUE
                        set/override setting (may be repeated)
--pdb                   enable pdb on failure

比較常用的有 --no-redirect-s 選項:

  • --no-redirect : 指的是不處理重定向,直接按照原始響應(yīng)返回即可;
  • -s:替換 settings.py 中的配置。常用的有設(shè)置 USER_AGENT 等。

3. 小結(jié)

本小節(jié)中我們簡單介紹了 Scrapy 的 Shell 模式以及 Response 類的一些原理。緊接著我們開始了 Scrapy Shell 實戰(zhàn),以廣州鏈家網(wǎng)為例,測試在 Shell 模式下使用 Selector 選擇器來解析網(wǎng)頁數(shù)據(jù),提取房屋標題、位置、價格等數(shù)據(jù)。下面一節(jié)我們會深入分析 Scrapy 框架中的 Request 和 Response ,包括解答今天的一個源碼追蹤作業(yè)。