<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                本文希望達到以下目標: 1. 簡要介紹Scarpy 2. 閱讀官網入門文檔并實現文檔中的范例 3. 使用Scarpy優豆瓣爬蟲的抓取 4. 制定下一步學習目標 > 初學`Scrapy`, 如有翻譯不當, 或者代碼錯誤, 請指出, 非常感謝 # 1\. Scrapy簡介 * * * > Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 可以應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。 > 其最初是為了頁面抓取 (更確切來說, 網絡抓取 )所設計的, 也可以應用在獲取API所返回的數據(例如 Amazon Associates Web Services ) 或者通用的網絡爬蟲。Scrapy用途廣泛,可以用于數據挖掘、監測和自動化測試 `Scrapy` 使用了 `Twisted`異步網絡庫來處理網絡通訊。整體架構大致如下 ![](https://box.kancloud.cn/2016-04-08_570718c75fdec.png) Scrapy Scrapy主要包括了以下組件: * 引擎(Scrapy): 用來處理整個系統的數據流處理, 觸發事務(框架核心) * 調度器(Scheduler): 用來接受引擎發過來的請求, 壓入隊列中, 并在引擎再次請求的時候返回. 可以想像成一個URL(抓取網頁的網址或者說是鏈接)的優先隊列, 由它來決定下一個要抓取的網址是什么, 同時去除重復的網址 * 下載器(Downloader): 用于下載網頁內容, 并將網頁內容返回給蜘蛛(Scrapy下載器是建立在twisted這個高效的異步模型上的) * 爬蟲(Spiders): 爬蟲是主要干活的, 用于從特定的網頁中提取自己需要的信息, 即所謂的實體(Item)。用戶也可以從中提取出鏈接,讓Scrapy繼續抓取下一個頁面 * 項目管道(Pipeline): 負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證實體的有效性、清除不需要的信息。當頁面被爬蟲解析后,將被發送到項目管道,并經過幾個特定的次序處理數據。 * 下載器中間件(Downloader Middlewares): 位于Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請求及響應。 * 爬蟲中間件(Spider Middlewares): 介于Scrapy引擎和爬蟲之間的框架,主要工作是處理蜘蛛的響應輸入和請求輸出。 * 調度中間件(Scheduler Middewares): 介于Scrapy引擎和調度之間的中間件,從Scrapy引擎發送到調度的請求和響應。 **Scrapy運行流程大概如下:** 1. 首先,引擎從調度器中取出一個鏈接(URL)用于接下來的抓取 2. 引擎把URL封裝成一個請求(Request)傳給下載器,下載器把資源下載下來,并封裝成應答包(Response) 3. 然后,爬蟲解析Response 4. 若是解析出實體(Item),則交給實體管道進行進一步的處理。 5. 若是解析出的是鏈接(URL),則把URL交給Scheduler等待抓取 # 2\. 安裝Scrapy * * * 使用以下命令: ~~~ sudo pip install virtualenv #安裝虛擬環境工具 virtualenv ENV #創建一個虛擬環境目錄 source ./ENV/bin/active #激活虛擬環境 pip install Scrapy #驗證是否安裝成功 pip list #輸出如下 cffi (0.8.6) cryptography (0.6.1) cssselect (0.9.1) lxml (3.4.1) pip (1.5.6) pycparser (2.10) pyOpenSSL (0.14) queuelib (1.2.2) Scrapy (0.24.4) setuptools (3.6) six (1.8.0) Twisted (14.0.2) w3lib (1.10.0) wsgiref (0.1.2) zope.interface (4.1.1) ~~~ [更多虛擬環境的操作可以查看我的博文](http://andrewliu.tk/2014/12/08/Virtualenv%E7%AE%80%E6%98%8E%E6%95%99%E7%A8%8B/) # 3\. Scrapy Tutorial * * * 在抓取之前, 你需要新建一個`Scrapy`工程. 進入一個你想用來保存代碼的目錄,然后執行: ~~~ $ scrapy startproject tutorial ~~~ 這個命令會在當前目錄下創建一個新目錄 tutorial, 它的結構如下: ~~~ . ├── scrapy.cfg └── tutorial ├── __init__.py ├── items.py ├── pipelines.py ├── settings.py └── spiders └── __init__.py ~~~ 這些文件主要是: * scrapy.cfg: 項目配置文件 * tutorial/: 項目python模塊, 之后您將在此加入代碼 * tutorial/items.py: 項目items文件 * tutorial/pipelines.py: 項目管道文件 * tutorial/settings.py: 項目配置文件 * tutorial/spiders: 放置spider的目錄 ## 3.1\. 定義Item Items是將要裝載抓取的數據的容器,它工作方式像 python 里面的字典,但它提供更多的保護,比如對未定義的字段填充以防止拼寫錯誤 通過創建`scrapy.Item類`, 并且定義類型為 `scrapy.Field` 的類屬性來聲明一個Item. 我們通過將需要的item模型化,來控制從 `dmoz.org` 獲得的站點數據,比如我們要獲得站點的名字,url 和網站描述,我們定義這三種屬性的域。在 tutorial 目錄下的 items.py 文件編輯 ~~~ from scrapy.item import Item, Field class DmozItem(Item): # define the fields for your item here like: name = Field() description = Field() url = Field() ~~~ ## 3.2\. 編寫Spider Spider 是用戶編寫的類, 用于從一個域(或域組)中抓取信息, 定義了用于下載的URL的初步列表, 如何跟蹤鏈接,以及如何來解析這些網頁的內容用于提取items。 要建立一個 Spider,繼承 `scrapy.Spider` 基類,并確定三個主要的、強制的屬性: * name:爬蟲的識別名,它必須是唯一的,在不同的爬蟲中你必須定義不同的名字. * start_urls:包含了Spider在啟動時進行爬取的url列表。因此,第一個被獲取到的頁面將是其中之一。后續的URL則從初始的URL獲取到的數據中提取。我們可以利用正則表達式定義和過濾需要進行跟進的鏈接。 * parse():是spider的一個方法。被調用時,每個初始URL完成下載后生成的 Response 對象將會作為唯一的參數傳遞給該函數。該方法負責解析返回的數據(response data),提取數據(生成item)以及生成需要進一步處理的URL的 Request 對象。 這個方法負責解析返回的數據、匹配抓取的數據(解析為 item )并跟蹤更多的 URL。 在 /tutorial/tutorial/spiders 目錄下創建 `dmoz_spider.py` ~~~ import scrapy class DmozSpider(scrapy.Spider): name = "dmoz" allowed_domains = ["dmoz.org"] start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" ] def parse(self, response): filename = response.url.split("/")[-2] with open(filename, 'wb') as f: f.write(response.body) ~~~ ## 3.3\. 爬取 當前項目結構 ~~~ ├── scrapy.cfg └── tutorial ├── __init__.py ├── items.py ├── pipelines.py ├── settings.py └── spiders ├── __init__.py └── dmoz_spider.py ~~~ 到項目根目錄, 然后運行命令: ~~~ $ scrapy crawl dmoz ~~~ 運行結果: ~~~ 2014-12-15 09:30:59+0800 [scrapy] INFO: Scrapy 0.24.4 started (bot: tutorial) 2014-12-15 09:30:59+0800 [scrapy] INFO: Optional features available: ssl, http11 2014-12-15 09:30:59+0800 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'tutorial.spiders', 'SPIDER_MODULES': ['tutorial.spiders'], 'BOT_NAME': 'tutorial'} 2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled extensions: LogStats, TelnetConsole, CloseSpider, WebService, CoreStats, SpiderState 2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMiddleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMiddleware, ChunkedTransferMiddleware, DownloaderStats 2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, UrlLengthMiddleware, DepthMiddleware 2014-12-15 09:30:59+0800 [scrapy] INFO: Enabled item pipelines: 2014-12-15 09:30:59+0800 [dmoz] INFO: Spider opened 2014-12-15 09:30:59+0800 [dmoz] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 2014-12-15 09:30:59+0800 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023 2014-12-15 09:30:59+0800 [scrapy] DEBUG: Web service listening on 127.0.0.1:6080 2014-12-15 09:31:00+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/> (referer: None) 2014-12-15 09:31:00+0800 [dmoz] DEBUG: Crawled (200) <GET http://www.dmoz.org/Computers/Programming/Languages/Python/Books/> (referer: None) 2014-12-15 09:31:00+0800 [dmoz] INFO: Closing spider (finished) 2014-12-15 09:31:00+0800 [dmoz] INFO: Dumping Scrapy stats: {'downloader/request_bytes': 516, 'downloader/request_count': 2, 'downloader/request_method_count/GET': 2, 'downloader/response_bytes': 16338, 'downloader/response_count': 2, 'downloader/response_status_count/200': 2, 'finish_reason': 'finished', 'finish_time': datetime.datetime(2014, 12, 15, 1, 31, 0, 666214), 'log_count/DEBUG': 4, 'log_count/INFO': 7, 'response_received_count': 2, 'scheduler/dequeued': 2, 'scheduler/dequeued/memory': 2, 'scheduler/enqueued': 2, 'scheduler/enqueued/memory': 2, 'start_time': datetime.datetime(2014, 12, 15, 1, 30, 59, 533207)} 2014-12-15 09:31:00+0800 [dmoz] INFO: Spider closed (finished) ~~~ ## 3.4\. 提取Items ### 3.4.1\. 介紹Selector 從網頁中提取數據有很多方法。Scrapy使用了一種基于 `XPath` 或者 `CSS 表達式`機制: Scrapy Selectors 出XPath表達式的例子及對應的含義: * `/html/head/title`: 選擇HTML文檔中 `<head>` 標簽內的 `<title>` 元素 * `/html/head/title/text()`: 選擇 `<title>` 元素內的文本 * `//td`: 選擇所有的 `<td>` 元素 * `//div[@class="mine"]`: 選擇所有具有`class="mine"` 屬性的 div 元素 > 等多強大的功能使用可以查看[XPath tutorial](http://www.w3school.com.cn/xpath/) 為了方便使用 XPaths,Scrapy 提供 Selector 類, 有四種方法 : * xpath():返回selectors列表, 每一個selector表示一個xpath參數表達式選擇的節點. * css() : 返回selectors列表, 每一個selector表示CSS參數表達式選擇的節點 * extract():返回一個unicode字符串,該字符串為XPath選擇器返回的數據 * re(): 返回unicode字符串列表,字符串作為參數由正則表達式提取出來 ### 3.4.2\. 取出數據 首先使用谷歌瀏覽器開發者工具, 查看網站源碼, 來看自己需要取出的數據形式(這種方法比較麻煩), 更簡單的方法是直接對感興趣的東西右鍵`審查元素`, 可以直接查看網站源碼 在查看網站源碼后, 網站信息在第二個`<ul>`內 ~~~ <ul class="directory-url" style="margin-left:0;"> <li><a href="http://www.pearsonhighered.com/educator/academic/product/0,,0130260363,00%2Ben-USS_01DBC.html" class="listinglink">Core Python Programming</a> - By Wesley J. Chun; Prentice Hall PTR, 2001, ISBN 0130260363\. For experienced developers to improve extant skills; professional level examples. Starts by introducing syntax, objects, error handling, functions, classes, built-ins. [Prentice Hall] <div class="flag"><a href="/public/flag?cat=Computers%2FProgramming%2FLanguages%2FPython%2FBooks&url=http%3A%2F%2Fwww.pearsonhighered.com%2Feducator%2Facademic%2Fproduct%2F0%2C%2C0130260363%2C00%252Ben-USS_01DBC.html"><img src="/img/flag.png" alt="[!]" title="report an issue with this listing"></a></div> </li> ...省略部分... </ul> ~~~ 那么就可以通過一下方式進行提取數據 ~~~ #通過如下命令選擇每個在網站中的 <li> 元素: sel.xpath('//ul/li') #網站描述: sel.xpath('//ul/li/text()').extract() #網站標題: sel.xpath('//ul/li/a/text()').extract() #網站鏈接: sel.xpath('//ul/li/a/@href').extract() #如前所述,每個 xpath() 調用返回一個 selectors 列表,所以我們可以結合 xpath() 去挖掘更深的節點。我們將會用到這些特性,所以: for sel in response.xpath('//ul/li') title = sel.xpath('a/text()').extract() link = sel.xpath('a/@href').extract() desc = sel.xpath('text()').extract() print title, link, desc ~~~ 在已有的爬蟲文件中修改代碼 ~~~ import scrapy class DmozSpider(scrapy.Spider): name = "dmoz" allowed_domains = ["dmoz.org"] start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/" ] def parse(self, response): for sel in response.xpath('//ul/li'): title = sel.xpath('a/text()').extract() link = sel.xpath('a/@href').extract() desc = sel.xpath('text()').extract() print title, link, desc ~~~ ### 3.4.3\. 使用item `Item`對象是自定義的python字典,可以使用標準的字典語法來獲取到其每個字段的值(字段即是我們之前用Field賦值的屬性) ~~~ >>> item = DmozItem() >>> item['title'] = 'Example title' >>> item['title'] 'Example title' ~~~ 一般來說,Spider將會將爬取到的數據以 Item 對象返回, 最后修改爬蟲類,使用 Item 來保存數據,代碼如下 ~~~ from scrapy.spider import Spider from scrapy.selector import Selector from tutorial.items import DmozItem class DmozSpider(Spider): name = "dmoz" allowed_domains = ["dmoz.org"] start_urls = [ "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/", "http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/", ] def parse(self, response): sel = Selector(response) sites = sel.xpath('//ul[@class="directory-url"]/li') items = [] for site in sites: item = DmozItem() item['name'] = site.xpath('a/text()').extract() item['url'] = site.xpath('a/@href').extract() item['description'] = site.xpath('text()').re('-\s[^\n]*\\r') items.append(item) return items ~~~ ## 3.5\. 使用Item Pipeline 當Item在Spider中被收集之后,它將會被傳遞到Item Pipeline,一些組件會按照一定的順序執行對Item的處理。 每個item pipeline組件(有時稱之為`ItemPipeline`)是實現了簡單方法的Python類。他們接收到Item并通過它執行一些行為,同時也決定此Item是否繼續通過pipeline,或是被丟棄而不再進行處理。 以下是item pipeline的一些典型應用: * 清理HTML數據 * 驗證爬取的數據(檢查item包含某些字段) * 查重(并丟棄) * 將爬取結果保存,如保存到數據庫、XML、JSON等文件中 >  編寫你自己的item pipeline很簡單,每個item pipeline組件是一個獨立的Python類,同時必須實現以下方法: ~~~ process_item(item, spider) #每個item pipeline組件都需要調用該方法,這個方法必須返回一個 Item (或任何繼承類)對象,或是拋出 DropItem異常,被丟棄的item將不會被之后的pipeline組件所處理。 #參數: item: 由 parse 方法返回的 Item 對象(Item對象) spider: 抓取到這個 Item 對象對應的爬蟲對象(Spider對象) open_spider(spider) #當spider被開啟時,這個方法被調用。 #參數: spider : (Spider object) – 被開啟的spider close_spider(spider) #當spider被關閉時,這個方法被調用,可以再爬蟲關閉后進行相應的數據處理。 #參數: spider : (Spider object) – 被關閉的spider ~~~ > 為JSON文件編寫一個items ~~~ from scrapy.exceptions import DropItem class TutorialPipeline(object): # put all words in lowercase words_to_filter = ['politics', 'religion'] def process_item(self, item, spider): for word in self.words_to_filter: if word in unicode(item['description']).lower(): raise DropItem("Contains forbidden word: %s" % word) else: return item ~~~ 在 settings.py 中設置`ITEM_PIPELINES`激活item pipeline,其默認為[] ~~~ ITEM_PIPELINES = {'tutorial.pipelines.FilterWordsPipeline': 1} ~~~ ## 3.6\. 存儲數據 使用下面的命令存儲為`json`文件格式 ~~~ scrapy crawl dmoz -o items.json ~~~ # 4\. Scarpy優化豆瓣爬蟲的抓取 * * * 主要針對之間寫過的豆瓣爬蟲進行重構: * [Python網絡爬蟲(二)--豆瓣抓站小計](http://andrewliu.tk/2014/12/05/Python%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB-%E4%BA%8C-%E8%B1%86%E7%93%A3%E6%8A%93%E7%AB%99%E5%B0%8F%E8%AE%A1/) * [豆瓣抓站重構第二版](http://andrewliu.tk/2014/12/15/Python-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%BB%AD-Queue/) 豆瓣有反爬蟲機制, 只成功了一次后, 就被`baned`后顯示403了, 下面說一下爬蟲結構 [完整的豆瓣爬蟲代碼鏈接](https://github.com/Andrew-liu/scrapy_example/tree/master/douban) ## 4.1\. Item ~~~ from scrapy.item import Item, Field class DoubanItem(Item): # define the fields for your item here like: # name = scrapy.Field() name = Field() #電影名稱 description = Field() #電影描述 url = Field() #抓取的url ~~~ ## 4.2\. Spider主程序 ~~~ #!/usr/bin/env python # -*- coding:utf-8 -*- """ 一個簡單的Python 爬蟲, 用于抓取豆瓣電影Top前250的電影的名稱描述等 Anthor: Andrew Liu Version: 0.0.3 Date: 2014-12-17 Language: Python2.7.8 Editor: Sublime Text2 Operate: 具體操作請看README.md介紹 """ from scrapy.contrib.spiders import CrawlSpider, Rule from scrapy.selector import Selector from douban.items import DoubanItem from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor class DoubanSpider(CrawlSpider) : name = "douban" allowed_domains = ["movie.douban.com"] start_urls = ["http://movie.douban.com/top250"] rules = ( #將所有符合正則表達式的url加入到抓取列表中 Rule(SgmlLinkExtractor(allow = (r'http://movie\.douban\.com/top250\?start=\d+&filter=&type=',))), #將所有符合正則表達式的url請求后下載網頁代碼, 形成response后調用自定義回調函數 Rule(SgmlLinkExtractor(allow = (r'http://movie\.douban\.com/subject/\d+', )), callback = 'parse_page', follow = True), ) def parse_page(self, response) : sel = Selector(response) item = DoubanItem() item['name'] = sel.xpath('//h1/span[@property="v:itemreviewed"]/text()').extract() item['description'] = sel.xpath('//div/span[@property="v:summary"]/text()').extract() item['url'] = response.url return item ~~~ ## 4.3\. 未來要解決的問題 * 頭部偽裝 * 表單提交 * 編碼轉換 > 豆瓣抓了一會兒, 還沒等我興奮就被禁掉了 [ban](http://doc.scrapy.org/en/latest/topics/practices.html#bans) ~~~ ... 2014-12-17 22:02:17+0800 [douban] DEBUG: Crawled (403) <GET http://www.douban.com/misc/sorry?original-url=http%3A%2F%2Fmovie.douban.com%2Fsubject%2F2209573%2F%3Ffrom%3Dsubject-page> (referer: http://movie.douban.com/subject/1849031/) 2014-12-17 22:02:17+0800 [douban] DEBUG: Ignoring response <403 http://www.douban.com/misc/sorry?original-url=http%3A%2F%2Fmovie.douban.com%2Fsubject%2F2209573%2F%3Ffrom%3Dsubject-page>: HTTP status code is not handled or not allowed 2014-12-17 22:02:17+0800 [douban] DEBUG: Crawled (403) <GET http://www.douban.com/misc/sorry?original-url=http%3A%2F%2Fmovie.douban.com%2Fsubject%2F1849031%2Fcomments%3Fsort%3Dtime> (referer: http://movie.douban.com/subject/1849031/) ... ~~~ # 5\. 參考鏈接 * * * * [Basic concepts](http://doc.scrapy.org/en/0.24/index.html#section-basics) * [What else? section in Scrapy at a glance](http://doc.scrapy.org/en/0.24/intro/overview.html#topics-whatelse) * [Item Pipeline](http://doc.scrapy.org/en/0.24/topics/item-pipeline.html#topics-item-pipeline) * [Scrapy Tutorial](http://doc.scrapy.org/en/0.24/intro/tutorial.html) * [BeautifulSoup](http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html) * [mechanize](http://wwwsearch.sourceforge.net/mechanize/) * [scrapy](http://scrapy.org/) * [Selectors documentation](http://doc.scrapy.org/en/0.24/topics/selectors.html#topics-selectors) * [scrapy 中文教程(爬cnbeta實例)](http://wsky.org/archives/191.html) * [dmoz](http://www.dmoz.org/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看