<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          5分鐘快速掌握 scrapy 爬蟲(chóng)框架

          共 8234字,需瀏覽 17分鐘

           ·

          2020-12-13 02:05

          號(hào)外:
          本號(hào)免費(fèi)提供 CSDN 資源下載,需要的伙伴公眾號(hào)后臺(tái)回復(fù)【CSDN】

          1. scrapy簡(jiǎn)介

          scrapy是基于事件驅(qū)動(dòng)的Twisted框架下用純python寫(xiě)的爬蟲(chóng)框架。很早之前就開(kāi)始用scrapy來(lái)爬取網(wǎng)絡(luò)上的圖片和文本信息,一直沒(méi)有把細(xì)節(jié)記錄下來(lái)。這段時(shí)間,因?yàn)楣ぷ餍枰种厥皊crapy爬蟲(chóng),本文和大家分享下,包你一用就會(huì), 歡迎交流。

          1.1 scrapy框架

          scrapy框架包括5個(gè)主要的組件和2個(gè)中間件Hook。
          • ENGIINE:整個(gè)框架的控制中心, 控制整個(gè)爬蟲(chóng)的流程。根據(jù)不同的條件添加不同的事件(就是用的Twisted)
          • SCHEDULER:事件調(diào)度器
          • DOWNLOADER:接收爬蟲(chóng)請(qǐng)求,從網(wǎng)上下載數(shù)據(jù)
          • SPIDERS:發(fā)起爬蟲(chóng)請(qǐng)求,并解析DOWNLOADER返回的網(wǎng)頁(yè)內(nèi)容,同時(shí)和數(shù)據(jù)持久化進(jìn)行交互,需要開(kāi)發(fā)者編寫(xiě)
          • ITEM PIPELINES:接收SPIDERS解析的結(jié)構(gòu)化的字段,進(jìn)行持久化等操作,需要開(kāi)發(fā)者編寫(xiě)
          • MIDDLEWARES:ENGIINESPIDERS, ENGIINEDOWNLOADER之間一些額外的操作,hook的方式提供給開(kāi)發(fā)者
          從上可知,我們只要實(shí)現(xiàn)SPIDERS(要爬什么網(wǎng)站,怎么解析)和ITEM PIPELINES(如何處理解析后的內(nèi)容)就可以了。其他的都是有框架幫你完成了。(圖片來(lái)自網(wǎng)絡(luò),如果侵權(quán)聯(lián)系必刪)

          1.2 scrapy數(shù)據(jù)流

          我們?cè)僭敿?xì)看下組件之間的數(shù)據(jù)流,會(huì)更清楚框架的內(nèi)部運(yùn)作。(圖片來(lái)自網(wǎng)絡(luò),如果侵權(quán)聯(lián)系必刪)


            1. SPIDERS發(fā)爬蟲(chóng)請(qǐng)求給ENGIINE, 告訴它任務(wù)來(lái)了

            1. ENGIINE將請(qǐng)求添加到SCHEDULER調(diào)度隊(duì)列里, 說(shuō)任務(wù)就交給你了,給我安排好

            1. SCHEDULER看看手里的爬取請(qǐng)求很多,挑一個(gè)給ENGIINE, 說(shuō)大哥幫忙轉(zhuǎn)發(fā)給下載DOWNLOADER

            1. ENGIINE:好的, DOWNLOADER你的任務(wù)來(lái)了

            1. DOWNLOADER:開(kāi)始下載了,下載好了,任務(wù)結(jié)果 交給ENGIINE

            1. ENGIINE將結(jié)果給SPIDERS, 你的一個(gè)請(qǐng)求下載好了,快去解析吧

            1. SPIDERS:好的,解析產(chǎn)生了結(jié)果字段。又給SPIDERS轉(zhuǎn)發(fā)給ITEM PIPELINES

            1. ITEM PIPELINES: 接收到字段內(nèi)容,保存起來(lái)。
          第1步到第8步,一個(gè)請(qǐng)求終于完成了。是不是覺(jué)得很多余?ENGIINE夾在中間當(dāng)傳話筒,能不能直接跳過(guò)?可以考慮跳過(guò)了會(huì)怎么樣。
          這里分析一下
          • SCHEDULER的作用:任務(wù)調(diào)度, 控制任務(wù)的并發(fā),防止機(jī)器處理不過(guò)來(lái)
          • ENGIINE:就是基于Twisted框架, 當(dāng)事件來(lái)(比如轉(zhuǎn)發(fā)請(qǐng)求)的時(shí)候,通過(guò)回調(diào)的方式來(lái)執(zhí)行對(duì)應(yīng)的事件。我覺(jué)得ENGIINE讓所有操作變的統(tǒng)一,都是按照事件的方式來(lái)組織其他組件, 其他組件以低耦合的方式運(yùn)作;對(duì)于一種框架來(lái)說(shuō),無(wú)疑是必備的。

          2. 基礎(chǔ):XPath

          寫(xiě)爬蟲(chóng)最重要的是解析網(wǎng)頁(yè)的內(nèi)容,這個(gè)部分就介紹下通過(guò)XPath來(lái)解析網(wǎng)頁(yè),提取內(nèi)容。

          2.1 HTML節(jié)點(diǎn)和屬性

          (圖片來(lái)自網(wǎng)絡(luò),如果侵權(quán)聯(lián)系必刪)

          2.2 解析語(yǔ)法

          • a / b:‘/’在 xpath里表示層級(jí)關(guān)系,左邊的 a是父節(jié)點(diǎn),右邊的 b是子節(jié)點(diǎn)
          • a // b:表示a下所有b,直接或者間接的
          • [@]:選擇具有某個(gè)屬性的節(jié)點(diǎn)
            • //div[@classs], //a[@x]:選擇具有 class屬性的 div節(jié)點(diǎn)、選擇具有 x屬性的 a節(jié)點(diǎn)
            • //div[@class="container"]:選擇具有 class屬性的值為 container的 div節(jié)點(diǎn)
          • //a[contains(@id, "abc")]:選擇 id屬性里有 abc的 a標(biāo)簽
          一個(gè)例子
          response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').get_all()
          #?獲取所有class屬性(css)為taglist的div,?下一個(gè)層ul下的所有l(wèi)i下所有a下所有img標(biāo)簽下data-original屬性

          #?data-original這里放的是圖片的url地址
          更多詳見(jiàn)
          http://zvon.org/comp/r/tut-XPath_1.html#Pages~List_of_XPaths

          3. 安裝部署

          Scrapy 是用純python編寫(xiě)的,它依賴(lài)于幾個(gè)關(guān)鍵的python包(以及其他包):
          • lxml 一個(gè)高效的XML和HTML解析器
          • parsel ,一個(gè)寫(xiě)在lxml上面的html/xml數(shù)據(jù)提取庫(kù),
          • w3lib ,用于處理URL和網(wǎng)頁(yè)編碼的多用途幫助程序
          • twisted 異步網(wǎng)絡(luò)框架
          • cryptography 和 pyOpenSSL ,處理各種網(wǎng)絡(luò)級(jí)安全需求
          #?安裝
          pip?install?scrapy

          4. 創(chuàng)建爬蟲(chóng)項(xiàng)目

          scrapy?startproject?sexy

          #
          ?創(chuàng)建一個(gè)后的項(xiàng)目目錄
          #?sexy
          #?│??scrapy.cfg
          #?│
          #?└─sexy
          #?????│??items.py
          #?????│??middlewares.py
          #?????│??pipelines.py
          #?????│??settings.py
          #?????│??__init__.py
          #?????│
          #?????├─spiders
          #?????│??│??__init__.py
          #?????│??│
          #?????│??└─__pycache__
          #?????└─__pycache__

          #
          ?執(zhí)行?需要到scrapy.cfg同級(jí)別的目錄執(zhí)行
          scrapy?crawl?sexy
          從上可知,我們要寫(xiě)的是spiders里的具體的spider類(lèi)和items.py和pipelines.py(對(duì)應(yīng)的ITEM PIPELINES

          5. 開(kāi)始scrapy爬蟲(chóng)

          5.1 簡(jiǎn)單而強(qiáng)大的spider

          這里實(shí)現(xiàn)的功能是從圖片網(wǎng)站中下載圖片,保存在本地, url做了脫敏。需要注意的點(diǎn)在注釋要標(biāo)明
          • 類(lèi)要繼承 scrapy.Spider
          • 取一個(gè)唯一的name
          • 爬取的網(wǎng)站url加到start_urls列表里
          • 重寫(xiě)parse利用xpath解析reponse的內(nèi)容
          可以看到parse實(shí)現(xiàn)的時(shí)候沒(méi)有轉(zhuǎn)發(fā)給ITEM PIPELINES,直接處理了。這樣簡(jiǎn)單的可以這么處理,如果業(yè)務(wù)很復(fù)雜,建議交給ITEM PIPELINES。后面會(huì)給例子
          #?目錄結(jié)果為:spiders/sexy_spider.py
          import?scrapy
          import?os
          import?requests
          import?time


          def?download_from_url(url):
          ????response?=?requests.get(url,?stream=True)
          ????if?response.status_code?==?requests.codes.ok:
          ????????return?response.content
          ????else:
          ????????print('%s-%s'?%?(url,?response.status_code))
          ????????return?None


          class?SexySpider(scrapy.Spider):
          ???#?如果有多個(gè)spider,?name要唯一
          ????name?=?'sexy'
          ????allowed_domains?=?['uumdfdfnt.94demo.com']
          ????allowed_urls?=?['http://uumdfdfnt.94demo.com/']

          ????#?需要爬取的網(wǎng)站url加到start_urls?list里
          ????start_urls?=?['http://uumdfdfnt.94demo.com/tag/dingziku/index.html']
          ????save_path?=?'/home/sexy/dingziku'

          ????def?parse(self,?response):
          ????????#?解析網(wǎng)站,獲取圖片列表
          ????????img_list?=?response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').getall()
          ????????time.sleep(1)

          ????????#?處理圖片,?具體業(yè)務(wù)操作,?可交給items,?見(jiàn)5.2?items例子
          ????????for?img_url?in?img_list:
          ????????????file_name?=?img_url.split('/')[-1]
          ????????????content?=?download_from_url(img_url)
          ????????????if?content?is?not?None:
          ????????????????with?open(os.path.join(self.save_path,?file_name),?'wb')?as?fw:
          ????????????????????fw.write(content)

          ????????#?自動(dòng)下一頁(yè)(見(jiàn)5.3?自動(dòng)下一頁(yè))
          ????????next_page?=?response.xpath('//div[@class="page?both"]/ul/a[text()="下一頁(yè)"]/@href').get()
          ????????if?next_page?is?not?None:
          ????????????next_page?=?response.urljoin(next_page)
          ????????????yield?scrapy.Request(next_page,?callback=self.parse)

          5.2 items和pipline例子

          這里說(shuō)明下兩個(gè)的作用
          • items:提供一個(gè)字段存儲(chǔ), spider會(huì)將數(shù)據(jù)存在這里
          • pipline:會(huì)從items取數(shù)據(jù),進(jìn)行業(yè)務(wù)操作,比如5.1中的保存圖片;又比如存儲(chǔ)到數(shù)據(jù)庫(kù)中等
          我們來(lái)改寫(xiě)下上面的例子
          • items.py其實(shí)就是定義字段scrapy.Field()
          import?scrapy
          class?SexyItem(scrapy.Item):
          ????#?define?the?fields?for?your?item?here?like:
          ????#?name?=?scrapy.Field()
          ????img_url?=?scrapy.Field()
          • spiders/sexy_spider.py
          import?scrapy
          import?os
          #?導(dǎo)入item
          from?..items?import?SexyItem

          class?SexySpider(scrapy.Spider):
          ???#?如果有多個(gè)spider,?name要唯一
          ????name?=?'sexy'
          ????allowed_domains?=?['uumdfdfnt.94demo.com']
          ????allowed_urls?=?['http://uumdfdfnt.94demo.com/']

          ????#?需要爬取的網(wǎng)站url加到start_urls?list里
          ????start_urls?=?['http://uumdfdfnt.94demo.com/tag/dingziku/index.html']
          ????save_path?=?'/home/sexy/dingziku'

          ????def?parse(self,?response):
          ????????#?解析網(wǎng)站,獲取圖片列表
          ????????img_list?=?response.xpath('//div[@class="taglist"]/ul//li//a//img/@data-original').getall()
          ????????time.sleep(1)

          ????????#?處理圖片,?具體業(yè)務(wù)操作,?可交給yield?items
          ????????for?img_url?in?img_list:
          ????????????items?=?SexyItem()
          ????????????items['img_url']?=?img_url
          ????????????yield?items
          • pipelines.py
          import?os
          import?requests


          def?download_from_url(url):
          ????response?=?requests.get(url,?stream=True)
          ????if?response.status_code?==?requests.codes.ok:
          ????????return?response.content
          ????else:
          ????????print('%s-%s'?%?(url,?response.status_code))
          ????????return?None


          class?SexyPipeline(object):

          ????def?__init__(self):
          ????????self.save_path?=?'/tmp'

          ????def?process_item(self,?item,?spider):
          ????????if?spider.name?==?'sexy':
          ????????????#?取出item里內(nèi)容
          ????????????img_url?=?item['img_url']
          ????????????
          ????????????#?業(yè)務(wù)處理
          ????????????file_name?=?img_url.split('/')[-1]
          ????????????content?=?download_from_url(img_url)
          ????????????if?content?is?not?None:
          ????????????????with?open(os.path.join(self.save_path,?file_name),?'wb')?as?fw:
          ????????????????????fw.write(content)
          ????????return?item
          • 重要的配置要開(kāi)啟settings.py中開(kāi)啟piplines類(lèi),數(shù)值表示優(yōu)先級(jí)
          ITEM_PIPELINES?=?{
          ???'sexy.pipelines.SexyPipeline':?300,
          }

          5.3 自動(dòng)下一頁(yè)

          有時(shí)候我們不僅要爬取請(qǐng)求頁(yè)面中的內(nèi)容,還要遞歸式的爬取里面的超鏈接url,特別是下一頁(yè)這種,解析內(nèi)容和當(dāng)前頁(yè)面相同的情況下。一種笨方法是手動(dòng)加到start_urls里。大家都是聰明人來(lái)試試這個(gè)。
          • 先在頁(yè)面解析下下一頁(yè)的url
          • scrapy.Request(next_page, callback=self.parse) 發(fā)起一個(gè)請(qǐng)求,并調(diào)用parse來(lái)解析,當(dāng)然你可以用其他的解析
          完美了,完整例子見(jiàn)5.1
          next_page?=?response.xpath('//div[@class="page?both"]/ul/a[text()="下一頁(yè)"]/@href').get()
          if?next_page?is?not?None:
          ???next_page?=?response.urljoin(next_page)
          ???yield?scrapy.Request(next_page,?callback=self.parse)

          5.4 中間件

          • 下載中間件 中間件的作用是提供一些常用的鉤子Hook來(lái)增加額外的操作。中間件的操作是在middlewares.py??梢钥吹街饕翘幚碚?qǐng)求process_request,響應(yīng)process_response和異常process_exception三個(gè)鉤子函數(shù)。
          • 處理請(qǐng)求process_request: 傳給DOWNLOADER之前做的操作
          • 響應(yīng)process_responseDOWNLOADERENGIINE響應(yīng)之前的操作
          這里舉一個(gè)添加模擬瀏覽器請(qǐng)求的方式,防止爬蟲(chóng)被封鎖。重寫(xiě)process_request
          from?scrapy.contrib.downloadermiddleware.useragent?import?UserAgentMiddleware
          import?random
          agents?=?['Mozilla/5.0?(compatible;?MSIE?9.0;?Windows?NT?6.1;?Trident/5.0;',
          ??????????????'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10.6;?rv,2.0.1)?Gecko/20100101?Firefox/4.0.1',
          ??????????????'Opera/9.80?(Macintosh;?Intel?Mac?OS?X?10.6.8;?U;?en)?Presto/2.8.131?Version/11.11',
          ??????????????'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_7_0)?AppleWebKit/535.11?(KHTML,?like?Gecko)?Chrome/17.0.963.56?Safari/535.11',
          ??????????????'Mozilla/4.0?(compatible;?MSIE?7.0;?Windows?NT?5.1;?360SE)']

          class?RandomUserAgent(UserAgentMiddleware):
          ????def?process_request(self,?request,?spider):
          ????????ua?=?random.choice(agents)
          ????????request.headers.setdefault('User-agent',ua,)
          統(tǒng)一要在settings.py中開(kāi)啟下載中間件,數(shù)值表示優(yōu)先級(jí)
          DOWNLOADER_MIDDLEWARES?=?{
          ????'sexy.middlewares.customUserAgent.RandomUserAgent':?20,
          }

          5.5 可用配置settings.py

          除了上面提供的pipline配置開(kāi)啟和中間件配置外,下面介紹幾個(gè)常用的配置
          • 爬蟲(chóng)機(jī)器人規(guī)則:ROBOTSTXT_OBEY = False, 如果要爬取的網(wǎng)站有設(shè)置robots.txt,最好設(shè)置為False
          • CONCURRENT_REQUESTS:并發(fā)請(qǐng)求
          • DOWNLOAD_DELAY:下載延遲,可以適當(dāng)配置,避免把網(wǎng)站也爬掛了。
          所有的配置詳見(jiàn) https://doc.scrapy.org/en/latest/topics/settings.html

          6. 總結(jié)

          相信從上面的介紹,你已經(jīng)可以動(dòng)手寫(xiě)一個(gè)你自己的爬蟲(chóng)了。我也完成了做筆記的任務(wù)了。scrapy還提供更加詳細(xì)的細(xì)節(jié),可參見(jiàn)https://docs.scrapy.org/en/latest/。
          最后總結(jié)如下:
          • scrapy是基于事件驅(qū)動(dòng)Twisted框架的爬蟲(chóng)框架。ENGIINE是核心,負(fù)責(zé)串起其他組件
          • 開(kāi)發(fā)只要編寫(xiě)spider和item pipline和中間件, download和schedule交給框架
          • scrapy crawl 你的爬蟲(chóng)name,name要唯一
          • 爬取的url放在start_urls, spider會(huì)自動(dòng)Request的,parse來(lái)解析
          • pipline和中間件要記得在settings中開(kāi)啟
          • 關(guān)注下settings的常用配置,需要時(shí)看下文檔

          -END-
          推薦閱讀
          Python 國(guó)產(chǎn)庫(kù)推薦:musicpy
          Python 下載的 11 種姿勢(shì),一種比一種高級(jí)!

          關(guān)注「Python 知識(shí)大全」,做全棧開(kāi)發(fā)工程師
          歲月有你 惜惜相處

          回復(fù) 【資料】獲取高質(zhì)量學(xué)習(xí)資料


          覺(jué)得本文對(duì)你有幫助?請(qǐng)分享給更多人
          點(diǎn)「在看」的人都變好看了哦
          瀏覽 21
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲热热 | 98无码人妻精品一区二区三区 | 婷婷五月六月 | 国产系列第一页 | 亚洲无码天堂在线视频 |