Scrapy提取項目

從網頁中提取數據,Scrapy 使用基於 XPathCSS 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:

/html/head/title:
這將選擇 HTML 文檔中的 元素中的 元素。</p> <p>/html/head/title/text(): 這將選擇 <title> 元素中的文本。</p> <p>//td: 這將選擇所有的 <td> 元素。</p> <p>//div[<a target="_blank" rel="nofollow noreferrer" href="https://github.com/class" title="@class">@class</a>=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。</p> <p>選擇器有四個基本的方法,如下所示:</p> <p>S.N.</p> <p>方法 & 描述</p> <p>extract()</p> <p>它返回一個unicode字符串以及所選數據</p> <p>re()</p> <p>它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取</p> <p>xpath()</p> <p>它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。</p> <p>css()</p> <p>它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。</p> <h2 id="在shell中使用選擇器">在Shell中使用選擇器</h2> <p>若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 <a target="_blank" rel="nofollow noreferrer" href="http://ipython.org/">IPython</a>。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「&」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:</p> <pre><code>scrapy shell "http://www.yiibai.com/scrapy/scrapy_environment.html"</code></pre> <p>shell 執行後結果如下圖所示:</p> <pre><code>D:first_scrapy>scrapy shell "http://www.yiibai.com/scrapy/scrapy_environment.html" 2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy) 2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0} 2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions: ['scrapy.extensions.telnet.TelnetConsole', 'scrapy.extensions.corestats.CoreStats'] 2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares: ['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware', 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 'scrapy.downloadermiddlewares.retry.RetryMiddleware', 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware', 'scrapy.downloadermiddlewares.stats.DownloaderStats'] 2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares: ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware', 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware', 'scrapy.spidermiddlewares.referer.RefererMiddleware', 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware', 'scrapy.spidermiddlewares.depth.DepthMiddleware'] 2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines: [] 2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023 2016-10-03 11:45:08 [scrapy] INFO: Spider opened 2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) <GET http://www.yiibai.com/robots.txt> (referer: None) 2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) <GET http://www.yiibai.com/scrapy/scrapy_environment.html> (referer: None) [s] Available Scrapy objects: [s] crawler <scrapy.crawler.Crawler object at 0x00000000042E3E80> [s] item {} [s] request <GET http://www.yiibai.com/scrapy/scrapy_environment.html> [s] response <200 http://www.yiibai.com/scrapy/scrapy_environment.html> [s] settings <scrapy.settings.Settings object at 0x00000000042E3E10> [s] spider <firstSpider 'first' at 0x47f9f28> [s] Useful shortcuts: [s] shelp() Shell help (print this help) [s] fetch(req_or_url) Fetch request (or URL) and update local objects [s] view(response) View response in a browser >>></code></pre> <p>當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。</p> <p>例如:</p> <pre><code>>>> response.xpath('//title') [<Selector xpath='//title' data=u'<title>Scrapyu5b89u88c5 - Scrapyu6559u7a0b</title>'>] >>> response.xpath('//title').extract() [u'<title>Scrapyu5b89u88c5 - Scrapyu6559u7a0b</title>'] >>> response.xpath('//title/text()') [<Selector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'>] >>> response.xpath('//title/text()').extract() [u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'] >>> response.xpath('//title/text()').extract() [u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'] >>> response.xpath('//title/text()').re('(w+):') [] >>></code></pre> <h2 id="提取數據">提取數據</h2> <p>從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。</p> <p>代碼的下面行顯示了不同類型的數據的提取:</p> <p>選擇 li 標籤內的數據:</p> <pre><code>response.xpath('//ul/li')</code></pre> <p>對於選擇描述:</p> <pre><code>response.xpath('//ul/li/text()').extract()</code></pre> <p>對於選擇網站標題:</p> <pre><code>response.xpath('//ul/li/a/text()').extract()</code></pre> <p>對於選擇網站的鏈接:</p> <pre><code>response.xpath('//ul/li/a/@href').extract()</code></pre> <p>下面的代碼用於演示上述提取的用法:</p> <pre><code>import scrapy class MyprojectSpider(scrapy.Spider): name = "project" 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</code></pre> </div></div></div><div class="functional-area-bottom"><div class="text-center"><div class="d-inline-block dropdown"><button type="button" id="dropdown-basic" aria-expanded="false" class="dropdown-toggle btn btn-outline-secondary btn-lg"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="share-nodes" class="svg-inline--fa fa-share-nodes " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M352 224c53 0 96-43 96-96s-43-96-96-96s-96 43-96 96c0 4 .2 8 .7 11.9l-94.1 47C145.4 170.2 121.9 160 96 160c-53 0-96 43-96 96s43 96 96 96c25.9 0 49.4-10.2 66.6-26.9l94.1 47c-.5 3.9-.7 7.8-.7 11.9c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-25.9 0-49.4 10.2-66.6 26.9l-94.1-47c.5-3.9 .7-7.8 .7-11.9s-.2-8-.7-11.9l94.1-47C302.6 213.8 326.1 224 352 224z"></path></svg><span class="ml-1 show-row">Share</span></button></div></div></div></article></div><div class="card-footer"><div class="row"><div class="col"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-left" class="svg-inline--fa fa-arrow-left " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"></path></svg><a href="/scrapy/scrapy-crawling">Scrapy執行爬行捉取</a></div><div class="col text-md-end"><a href="/scrapy/scrapy-using-item"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-right" class="svg-inline--fa fa-arrow-right " role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z"></path></svg>Scrapy使用項目</a></div></div></div></div></div></div></div></div><footer class="bg-white py-5 font-size-14" id="footer"><div class="container"><div class="row"><dl class="col-6 col-md-3 d-none d-sm-block"><dt class="h6">鏈接</dt><dd class="my-1"><a class="text-secondary" href="https://www.ecool.shop/" title="Ecool Shop">Ecool Shop</a></dd></dl></div><hr class="mt-2 mb-4"/><div class="row"><div class="col-md-12"><div class="text-secondary text-center"> Copyright © 2015-2023 億聚網.</div></div></div></div></footer><script src="/_next/static/chunks/webpack-546743ddf7e8cb4f.js" async=""></script><script src="/_next/static/chunks/bce60fc1-3d5ef5c4572453f6.js" async=""></script><script src="/_next/static/chunks/698-b4ee1b293f5fb4bc.js" async=""></script><script src="/_next/static/chunks/main-app-a5eb339177c85de1.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/1c4d07c82cde5388.css\",{\"as\":\"style\"}]\n0:\"$L2\"\n"])</script><script>self.__next_f.push([1,"3:I{\"id\":2353,\"chunks\":[\"272:static/chunks/webpack-546743ddf7e8cb4f.js\",\"253:static/chunks/bce60fc1-3d5ef5c4572453f6.js\",\"698:static/chunks/698-b4ee1b293f5fb4bc.js\"],\"name\":\"default\",\"async\":false}\n5:I{\"id\":43012,\"chunks\":[\"470:static/chunks/app/global-error-2d20c7d510a72141.js\"],\"name\":\"\",\"async\":false}\n6:I{\"id\":67676,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"210:static/chunks/ce69f5c4-ada3b84c9854a250.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652-2922f1746919c870"])</script><script>self.__next_f.push([1,".js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"928:static/chunks/928-e2c979bb342b0445.js\",\"285:static/chunks/285-4809214f326cf011.js\",\"185:static/chunks/app/layout-491b43680903f5ac.js\"],\"name\":\"\",\"async\":false}\n7:I{\"id\":29099,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"210:static/chunks/ce69f5c4-ada3b84c9854a250.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652-2922f1746919c870.js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"928:static/chunks/928-e2c979bb342b0445.js\""])</script><script>self.__next_f.push([1,",\"285:static/chunks/285-4809214f326cf011.js\",\"185:static/chunks/app/layout-491b43680903f5ac.js\"],\"name\":\"\",\"async\":false}\nb:I{\"id\":49180,\"chunks\":[\"272:static/chunks/webpack-546743ddf7e8cb4f.js\",\"253:static/chunks/bce60fc1-3d5ef5c4572453f6.js\",\"698:static/chunks/698-b4ee1b293f5fb4bc.js\"],\"name\":\"default\",\"async\":false}\nc:I{\"id\":92306,\"chunks\":[\"272:static/chunks/webpack-546743ddf7e8cb4f.js\",\"253:static/chunks/bce60fc1-3d5ef5c4572453f6.js\",\"698:static/chunks/698-b4ee1b293f5fb4bc.js\"],\"name\":\"default\",\"async\""])</script><script>self.__next_f.push([1,":false}\n"])</script><script>self.__next_f.push([1,"2:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1c4d07c82cde5388.css\",\"precedence\":\"next\"}]],[\"$\",\"$L3\",null,{\"buildId\":\"PeSdcBxKDNQIZlulyUEdm\",\"assetPrefix\":\"\",\"initialCanonicalUrl\":\"/scrapy/scrapy-extracting-items\",\"initialTree\":[\"\",{\"children\":[[\"slug\",\"scrapy\",\"d\"],{\"children\":[[\"post\",\"scrapy-extracting-items\",\"d\"],{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialHead\":[\"$L4\",null],\"globalErrorComponent\":\"$5\",\"notFound\":[\"$\",\"html\",null,{\"lang\":\"zh-Hant-TW\",\"children\":[[\"$\",\"meta\",null,{\"name\":\"viewport\",\"content\":\"minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover\"}],[\"$\",\"meta\",null,{\"charSet\":\"utf-8\"}],[\"$\",\"link\",null,{\"rel\":\"icon\",\"href\":\"/favicon.png\"}],[\"$\",\"$L6\",null,{\"async\":true,\"src\":\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1574283203161704\"}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$L8\",[\"$L9\",[],[\"$\",\"div\",null,{\"className\":\"page-content\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[\"$\",\"div\",null,{\"className\":\"box-404-wrap\",\"children\":[\"$\",\"div\",null,{\"className\":\"box\",\"children\":[\"$\",\"div\",null,{\"className\":\"d-flex flex-column align-items-center\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-wrap\",\"children\":[\"$\",\"h1\",null,{\"data-t\":\"404\",\"className\":\"h1\",\"children\":\"404\"}]}],[\"$\",\"div\",null,{\"className\":\"text-center mt-2\",\"children\":\"很抱歉,找不到此頁面! \"}],[\"$\",\"div\",null,{\"className\":\"mt-4\",\"children\":[\"$\",\"a\",null,{\"role\":\"button\",\"tabindex\":\"0\",\"href\":\"/\",\"className\":\"btn btn-primary\",\"children\":\"可前往首頁重新尋找頁面\"}]}]]}]}]}]}]}]],[\"$\",\"footer\",null,{\"className\":\"bg-white py-5 font-size-14\",\"id\":\"footer\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"dl\",null,{\"className\":\"col-6 col-md-3 d-none d-sm-block\",\"children\":[[\"$\",\"dt\",null,{\"className\":\"h6\",\"children\":\"鏈接\"}],[\"$\",\"dd\",null,{\"className\":\"my-1\",\"children\":[\"$\",\"a\",null,{\"className\":\"text-secondary\",\"href\":\"https://www.ecool.shop/\",\"title\":\"Ecool Shop\",\"children\":\"Ecool Shop\"}]}]]}]}],[\"$\",\"hr\",null,{\"className\":\"mt-2 mb-4\"}],[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"div\",null,{\"className\":\"col-md-12\",\"children\":[\"$\",\"div\",null,{\"className\":\"text-secondary text-center\",\"children\":\" Copyright © 2015-2023 億聚網.\"}]}]}]]}]}]]}]}]]}],\"asNotFound\":false,\"children\":[[\"$\",\"html\",null,{\"lang\":\"zh-Hant-TW\",\"children\":[[\"$\",\"meta\",null,{\"name\":\"viewport\",\"content\":\"minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover\"}],[\"$\",\"meta\",null,{\"charSet\":\"utf-8\"}],[\"$\",\"link\",null,{\"rel\":\"icon\",\"href\":\"/favicon.png\"}],[\"$\",\"$L6\",null,{\"async\":true,\"src\":\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1574283203161704\"}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L7\",null,{\"children\":[\"$La\",[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"hasLoading\":false,\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"notFound\":[\"$\",\"div\",null,{\"className\":\"page-content\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[\"$\",\"div\",null,{\"className\":\"box-404-wrap\",\"children\":[\"$\",\"div\",null,{\"className\":\"box\",\"children\":[\"$\",\"div\",null,{\"className\":\"d-flex flex-column align-items-center\",\"children\":[[\"$\",\"div\",null,{\"className\":\"text-wrap\",\"children\":[\"$\",\"h1\",null,{\"data-t\":\"404\",\"className\":\"h1\",\"children\":\"404\"}]}],[\"$\",\"div\",null,{\"className\":\"text-center mt-2\",\"children\":\"很抱歉,找不到此頁面! \"}],[\"$\",\"div\",null,{\"className\":\"mt-4\",\"children\":[\"$\",\"a\",null,{\"role\":\"button\",\"tabindex\":\"0\",\"href\":\"/\",\"className\":\"btn btn-primary\",\"children\":\"可前往首頁重新尋找頁面\"}]}]]}]}]}]}]}],\"notFoundStyles\":[],\"childProp\":{\"current\":[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",[\"slug\",\"scrapy\",\"d\"],\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"hasLoading\":false,\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\",\"childProp\":{\"current\":[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",[\"slug\",\"scrapy\",\"d\"],\"children\",[\"post\",\"scrapy-extracting-items\",\"d\"],\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"hasLoading\":false,\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\",\"childProp\":{\"current\":[\"$Ld\",null],\"segment\":\"__PAGE__\"},\"styles\":[]}],\"segment\":[\"post\",\"scrapy-extracting-items\",\"d\"]},\"styles\":[]}],\"segment\":[\"slug\",\"scrapy\",\"d\"]},\"styles\":[]}],[\"$\",\"footer\",null,{\"className\":\"bg-white py-5 font-size-14\",\"id\":\"footer\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"dl\",null,{\"className\":\"col-6 col-md-3 d-none d-sm-block\",\"children\":[[\"$\",\"dt\",null,{\"className\":\"h6\",\"children\":\"鏈接\"}],[\"$\",\"dd\",null,{\"className\":\"my-1\",\"children\":[\"$\",\"a\",null,{\"className\":\"text-secondary\",\"href\":\"https://www.ecool.shop/\",\"title\":\"Ecool Shop\",\"children\":\"Ecool Shop\"}]}]]}]}],[\"$\",\"hr\",null,{\"className\":\"mt-2 mb-4\"}],[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"div\",null,{\"className\":\"col-md-12\",\"children\":[\"$\",\"div\",null,{\"className\":\"text-secondary text-center\",\"children\":\" Copyright © 2015-2023 億聚網.\"}]}]}]]}]}]]}]}]]}],null]}]]\n"])</script><script>self.__next_f.push([1,"e:I{\"id\":43817,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"210:static/chunks/ce69f5c4-ada3b84c9854a250.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652-2922f1746919c870.js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"928:static/chunks/928-e2c979bb342b0445.js\",\"285:static/chunks/285-4809214f326cf011.js\",\"185:static/chunks/app/layout-491b43680903f5ac.js\"],\"name\":\"\",\"async\":false}\nf:I{\"id\":77095,\"chunks\":[\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"91:static/chunks/app/c"])</script><script>self.__next_f.push([1,"ategory/[slug]/page-bbf4c946a9f81329.js\"],\"name\":\"\",\"async\":false}\n9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"8:[\"$\",\"div\",null,{\"className\":\"shadow-sm\",\"id\":\"sf-header\",\"children\":[[\"$\",\"$Le\",null,{}],[\"$\",\"div\",null,{\"className\":\"sub-head d-lg-flex bg-white\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[\"$\",\"div\",null,{\"className\":\"tag-container-outer\",\"children\":[[\"$\",\"div\",null,{\"className\":\"tag-container\",\"children\":[[\"$\",\"span\",\"java\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/java\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"Java技術\"}]}],[\"$\",\"span\",\"web\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/web\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"Web開發\"}]}],[\"$\",\"span\",\"hightlang\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/hightlang\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"高級語言\"}]}],[\"$\",\"span\",\"misc\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/misc\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"其他技術\"}]}],[\"$\",\"span\",\"script\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/script\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"腳本語言\"}]}],[\"$\",\"span\",\"database\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/database\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"數據庫\"}]}],[\"$\",\"span\",\"bigdata\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/bigdata\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"大數據教程\"}]}],[\"$\",\"span\",\"xml\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/xml\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"XML技術\"}]}],[\"$\",\"span\",\"zhuanyejiaoyu\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/zhuanyejiaoyu\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"專業教育\"}]}],[\"$\",\"span\",\"framework\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/framework\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"框架\"}]}],[\"$\",\"span\",\"software\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/software\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"軟件工具教程\"}]}],[\"$\",\"span\",\"telecom\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/telecom\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"通信技術\"}]}],[\"$\",\"span\",\"5f75e0e8c632ea000650d41e\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/microsoft-technology\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"微軟技術\"}]}],[\"$\",\"span\",\"quality\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/quality\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"軟件測試\"}]}],[\"$\",\"span\",\"mobile-dev\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/mobile-dev\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"手機開發\"}]}],[\"$\",\"span\",\"frontend\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/frontend\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"前端技術\"}]}],[\"$\",\"span\",\"5f75e2d9c632ea000650d488\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/artificial-intelligence\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"人工智能\"}]}],[\"$\",\"span\",\"how2code\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/how2code\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"實例代碼\"}]}]]}],[\"$\",\"div\",null,{\"className\":\"gradient-block\"}]]}]}]}]]}]\n"])</script><script>self.__next_f.push([1,"a:[\"$\",\"div\",null,{\"className\":\"shadow-sm\",\"id\":\"sf-header\",\"children\":[[\"$\",\"$Le\",null,{}],[\"$\",\"div\",null,{\"className\":\"sub-head d-lg-flex bg-white\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[\"$\",\"div\",null,{\"className\":\"tag-container-outer\",\"children\":[[\"$\",\"div\",null,{\"className\":\"tag-container\",\"children\":[[\"$\",\"span\",\"java\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/java\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"Java技術\"}]}],[\"$\",\"span\",\"web\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/web\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"Web開發\"}]}],[\"$\",\"span\",\"hightlang\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/hightlang\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"高級語言\"}]}],[\"$\",\"span\",\"misc\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/misc\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"其他技術\"}]}],[\"$\",\"span\",\"script\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/script\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"腳本語言\"}]}],[\"$\",\"span\",\"database\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/database\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"數據庫\"}]}],[\"$\",\"span\",\"bigdata\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/bigdata\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"大數據教程\"}]}],[\"$\",\"span\",\"xml\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/xml\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"XML技術\"}]}],[\"$\",\"span\",\"zhuanyejiaoyu\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/zhuanyejiaoyu\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"專業教育\"}]}],[\"$\",\"span\",\"framework\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/framework\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"框架\"}]}],[\"$\",\"span\",\"software\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/software\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"軟件工具教程\"}]}],[\"$\",\"span\",\"telecom\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/telecom\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"通信技術\"}]}],[\"$\",\"span\",\"5f75e0e8c632ea000650d41e\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/microsoft-technology\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"微軟技術\"}]}],[\"$\",\"span\",\"quality\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/quality\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"軟件測試\"}]}],[\"$\",\"span\",\"mobile-dev\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/mobile-dev\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"手機開發\"}]}],[\"$\",\"span\",\"frontend\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/frontend\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"前端技術\"}]}],[\"$\",\"span\",\"5f75e2d9c632ea000650d488\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/artificial-intelligence\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"人工智能\"}]}],[\"$\",\"span\",\"how2code\",{\"className\":\"tag-nav__item me-3\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/category/how2code\",\"className\":\"text-secondNav\",\"prefetch\":false,\"children\":\"實例代碼\"}]}]]}],[\"$\",\"div\",null,{\"className\":\"gradient-block\"}]]}]}]}]]}]\n"])</script><script>self.__next_f.push([1,"10:I{\"id\":48364,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652-2922f1746919c870.js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"507:static/chunks/507-b7b248284dd3c803.js\",\"928:static/chunks/928-e2c979bb342b0445.js\",\"27:static/chunks/app/[slug]/[post]/page-f1024873a96f4ead.js\"],\"name\":\"\",\"async\":false}\n22:I{\"id\":84010,\"chunks\":[\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"91:static/chunks/app/category/[slug]/page-bbf4c946a9f81329"])</script><script>self.__next_f.push([1,".js\"],\"name\":\"\",\"async\":false}\n23:I{\"id\":9362,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652-2922f1746919c870.js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"507:static/chunks/507-b7b248284dd3c803.js\",\"190:static/chunks/app/article/[slug]/page-8819d505c1df94c3.js\"],\"name\":\"\",\"async\":false}\n25:I{\"id\":91947,\"chunks\":[\"957:static/chunks/59925f94-6302db480f248368.js\",\"703:static/chunks/703-ad7f7a9d88b70895.js\",\"652:static/chunks/652"])</script><script>self.__next_f.push([1,"-2922f1746919c870.js\",\"814:static/chunks/814-8c170bd1a2e2c86e.js\",\"507:static/chunks/507-b7b248284dd3c803.js\",\"928:static/chunks/928-e2c979bb342b0445.js\",\"27:static/chunks/app/[slug]/[post]/page-f1024873a96f4ead.js\"],\"name\":\"\",\"async\":false}\n11:T912,"])</script><script>self.__next_f.push([1,"\u003ch2\u003e Scrapy是什麼? \u003c/h2\u003e \n\u003cdiv\u003e\n Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。 \n \u003cbr\u003e \n \u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-1.png\" alt=\"Scrapy教程\"\u003e \n \u003cbr\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n\u003c/div\u003e \n\u003ch2\u003e 歷史 \u003c/h2\u003e \n\u003cdiv\u003e\n Scrapy最初是在 2008年6月26日在BSD許可協議下發布,並在2015年6月發佈的一個里程碑版本1.0。 \n\u003c/div\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 爲什麼要使用Scrapy? \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它更容易構建和大規模的抓取項目; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它內置的機制被稱爲選擇器,用於從網站(網頁)上提取數據; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它異步處理請求,速度十分快; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它可以使用 \n \u003ca href=\"http://doc.scrapy.org/en/latest/topics/autothrottle.html\"\u003e自動調節機制\u003c/a\u003e自動調整爬行速度; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 確保開發人員可訪問性; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n Scrapy的特點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy是一個開源和免費使用的網絡爬蟲框架; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy生成格式導出如:JSON,CSV和XML; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy內置支持從源代碼,使用XPath或CSS表達式的選擇器來提取數據; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy基於爬蟲,允許以自動方式從網頁中提取數據; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 優點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy很容易擴展,快速和功能強大; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 這是一個跨平臺應用程序框架(在Windows,Linux,Mac\u0026nbsp;OS和BSD)。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy請求調度和異步處理; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy附帶了一個名爲Scrapyd的內置服務,它允許使用JSON\u0026nbsp;Web服務上傳項目和控制蜘蛛。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 也能夠刮削任何網站,即使該網站不具有原始數據訪問API; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 缺點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy只面向Python2.7+以上版本; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 不同的操作系統安裝不太相同; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"12:T154d,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n 在本章中,我們將瞭解如何安裝和設置Scrapy。Scrapy必須與Python一起安裝。 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy可以通過使用 pip 進行安裝。運行以下命令: \n \u003c/div\u003e \n \u003cpre\u003epip install Scrapy\u003c/pre\u003e \n \u003ch2\u003e Windows系統上安裝(本教程) \u003c/h2\u003e \n \u003cdiv\u003e \n \u003cdiv\u003e\n 在Window系統上安裝Scrapy,是一個比較複雜的事項,在寫本教程的時候,看到網上有人說用了3天時間才裝好,嚇我一跳,不過還好,我也算是比較喜歡折騰的那麼一個人。需要一點點耐心就好。 下載文件地址 -\u0026nbsp; \n \u003ca href=\"http://pan.baidu.com/s/1nv6ObKt\"\u003ehttp://pan.baidu.com/s/1nv6ObKt\u003c/a\u003e \n \u003c/div\u003e 注:Windows操作系統是不支持Python3 的 Scrapy。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e 從\u0026nbsp;\u003ca href=\"https://www.python.org/downloads/\"\u003ePython\u003c/a\u003e\u0026nbsp;安裝 Python2.7 \u003c/p\u003e \n \u003cdiv\u003e\n 添加下面的路徑到PATH設置環境變量: \n \u003c/div\u003e \u003cpre\u003eC:\\Python27\\;C:\\Python27\\Scripts\\;\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以通過使用以下命令來檢查Python版本: \n \u003c/div\u003e \u003cpre\u003epython --version\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 安裝\u0026nbsp;\u003ca href=\"http://slproweb.com/products/Win32OpenSSL.html\"\u003eOpenSSL\u003c/a\u003e\u0026nbsp;或下載地址 :\u003ca href=\"http://www.egenix.com/cryptodownload/?file=egenix-pyopenssl-0.13.0_1.0.0g_1.win-amd64-py2.7.msi\"\u003ehttp://www.egenix.com/cryptodownload/?file=egenix-pyopenssl-0.13.0_1.0.0g_1.win-amd64-py2.7.msi\u003c/a\u003e(重點)\u003cbr\u003e 添加 C:\\OpenSSL-Win64\\bin\u0026nbsp;在您的系統環境變量中; \u003c/p\u003e \n \u003cdiv\u003e\n 注:OpenSSL預裝在所有的操作系統(除了Windows)。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 安裝\u0026nbsp;\u003ca href=\"http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF\"\u003eVisual C++ 2008\u003c/a\u003e\u0026nbsp;再發行組件或\u003ca href=\"http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF\"\u003eVisual C++ 2008 Redistributables\u003c/a\u003e\u0026nbsp;和\u0026nbsp;\u003ca href=\"http://slproweb.com/download/Win64OpenSSL-1_0_1f.exe\"\u003eWin64 OpenSSL v1.0.1f\u003c/a\u003e \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cul\u003e \n \u003cli\u003e 安裝\u0026nbsp;\u003ca href=\"http://sourceforge.net/projects/pywin32/\"\u003epywin32\u003c/a\u003e\u0026amp;amd64 \u003c/li\u003e \n \u003cli\u003e 安裝 Python2.7.9 以下的\u0026nbsp;\u003ca href=\"https://pip.pypa.io/en/latest/installing/\"\u003epip\u003c/a\u003e\u0026nbsp;或者下載地址:\u0026nbsp;\u003ca href=\"https://pypi.python.org/pypi/setuptools#files\"\u003ehttps://pypi.python.org/pypi/setuptools#files\u003c/a\u003e\u003ca href=\"https://pypi.python.org/pypi/setuptools#files\"\u003e\u0026nbsp;\u003c/a\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cul\u003e \n \u003cli\u003e 您可以通過使用以下命令來檢查 pip 版本: \u003cpre\u003epip --version\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 安裝twisted,下載地址 -\u003ca href=\"https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0\"\u003ehttps://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0\u003c/a\u003e \u003c/li\u003e \n \u003cli\u003e 安裝\u0026nbsp;zope 接口:\u003ca href=\"https://pypi.python.org/pypi/zope.interface/4.1.0\"\u003ehttps://pypi.python.org/pypi/zope.interface/4.1.0\u003c/a\u003e\u0026nbsp;選擇倒數第二個\u0026nbsp;\u003ca href=\"https://pypi.python.org/packages/2.7/z/zope.interface/zope.interface-4.1.0.win32-py2.7.exe#md5=c0100a3cd6de6ecc3cd3b4d678ec7931\"\u003ezope.interface-4.1.0.win32-py2.7.exe\u003c/a\u003e\u0026nbsp;\u003cbr\u003e \u003c/li\u003e \n \u003cli\u003e 安裝 lxml ,版本要選對應系統,錯誤的是用不了的。下載地址:\u0026nbsp;\u003ca href=\"https://pypi.python.org/pypi/lxml/3.2.3\"\u003ehttps://pypi.python.org/pypi/lxml/3.2.3\u003c/a\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cul\u003e \n \u003cli\u003e 要安裝scrapy,運行以下命令: \u003cpre\u003epip install Scrapy\u003c/pre\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cdiv\u003e\n 成功後,界面長這樣 -\u0026nbsp; \n \u003cbr\u003e \n \u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-2.png\" alt=\"Scrapy安裝\"\u003e \n \u003cbr\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e Ubuntu系統 \u003c/h2\u003e \n \u003cp\u003e Python的最新版本是預先安裝在Ubuntu操作系統。使用由 Scrapinghub 提供\u0026nbsp;Ubuntu 的軟件包 apt-get。要使用這些軟件包: \u003c/p\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 需要輸入用於登錄\u0026nbsp;Scrapy\u0026nbsp;包 APT 的 GPG密鑰: \n \u003c/div\u003e \u003cpre\u003esudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 627220E7\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 接下來,使用下面的命令來創建 /etc/apt/sources.list.d/scrapy.list 文件: \n \u003c/div\u003e \u003cpre\u003eecho 'deb http://archive.scrapy.org/ubuntu scrapy main'| sudo tee /etc/apt/sources.list.d/scrapy.list\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 更新軟件包列表並安裝scrapy: \n \u003c/div\u003e \u003cpre\u003esudo apt-get update \u0026amp;\u0026amp; sudo apt-get install scrapy\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e Archlinux系統 \u003c/h2\u003e \n \u003cdiv\u003e\n 可以使用下面的命令從AUR\u0026nbsp;Scrapy 包安裝 Scrapy: \n \u003c/div\u003e \n \u003cpre\u003eyaourt -S scrapy\u003c/pre\u003e \n \u003ch2\u003e Mac OS X系統 \u003c/h2\u003e \n \u003cdiv\u003e\n 使用下面的命令來安裝 Xcode 命令行工具: \n \u003c/div\u003e \n \u003cpre\u003excode-select--install\u003c/pre\u003e \n \u003cdiv\u003e\n 而不是使用系統的Python,安裝新的更新版本,不與系統的其餘部分衝突。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e 安裝\u003ca href=\"http://brew.sh/\"\u003ehomebrew\u003c/a\u003e \u003c/li\u003e \n \u003cli\u003e 設置環境變量 PATH 指定\u0026nbsp;homebrew\u0026nbsp;包在系統軟件包前使用: \u003cpre\u003eecho \"export PATH=/usr/local/bin:/usr/local/sbin:$PATH\"\u0026gt;\u0026gt;~/.bashrc\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 變更完成後,重新加載 .bashrc 使用下面的命令: \u003cpre\u003esource ~/.bashrc\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 接下來,使用下面的命令安裝\u0026nbsp;Python: \u003cpre\u003ebrew install python\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 接下來,安裝scrapy: \u003cpre\u003epip install Scrapy\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"13:T13b9,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n Scrapy命令行工具用於控制Scrapy,它通常被稱爲「Scrapy工具」。它包括用於不同對象的參數和選項組的命令。 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 配置設置 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n scrapy\u0026nbsp;會找到\u0026nbsp;scrapy.cfg\u0026nbsp;文件中設置的配置。如下面提到的: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e C:\\scrapy(project folder)\\scrapy.cfg\u0026nbsp;在系統中; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e ~/.config/scrapy.cfg ($XDG_CONFIG_HOME)\u0026nbsp;and\u0026nbsp;~/.scrapy.cfg ($HOME)\u0026nbsp;,這些是全局設置 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以在項目的根目錄裏面找到 scrapy.cfg 這個文件。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n Scrapy還可以使用以下的環境變量來配置: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_SETTINGS_MODULE \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_PROJECT \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_PYTHON_SHELL \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 默認Scrapy項目結構 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 下面的結構顯示 Scrapy項目的默認文件結構: \n \u003c/div\u003e \n \u003cpre\u003escrapy.cfg - Deploy the configuration file\r\nproject_name/ - Name of the project\r\n _init_.py\r\n items.py - It is project's items file\r\n pipelines.py - It is project's pipelines file\r\n settings.py - It is project's settings file\r\n spiders - It is the spiders directory\r\n _init_.py\r\n spider_name.py\r\n . . .\r\u003c/pre\u003e \n \u003cdiv\u003e\n scrapy.cfg 文件是在項目的根目錄,其中包括項目名稱與項目設置。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cpre\u003e[settings]\r\ndefault = [name of the project].settings\r\n\r\n[deploy]\r\n#url = http://localhost:6800/\r\nproject = [name of the project]\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用Scrapy工具 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 通過使用Scrapy工具,它會提供一些可使用以的命令如下所示: \n \u003c/div\u003e \n \u003cpre\u003eScrapy X.Y - no active project\r\nUsage:\r\n scrapy [options] [arguments]\r\nAvailable commands:\r\n crawl It puts spider (handle the URL) to work for crawling data\r\n fetch It fetches the response from the given URL\r\u003c/pre\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 創建項目 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n 您可以使用下面的命令來創建 Scrapy 項目: \n \u003c/div\u003e \n \u003cpre\u003escrapy startproject scrapy_project\r\u003c/pre\u003e \n \u003cdiv\u003e\n 這將創建一個名爲\u0026nbsp;project_name\u0026nbsp;的項目目錄。接下來,進入新創建的項目,使用下面的命令: \n \u003c/div\u003e \n \u003cpre\u003ecd scrapy_project\r\u003c/pre\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 控制項目 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n 您可以控制項目,並通過使用Scrapy工具,也創造了新的蜘蛛(spider),使用下面的命令進行管理: \n \u003c/div\u003e \n \u003cpre\u003escrapy genspider mydomain yiibai.com\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如:抓取等等的命令在 Scrapy 項目中的使用。這裏所有命令在接下來 Scrapy 項目內使用運行。 \n \u003c/div\u003e \n \u003cdiv\u003e\n Scrapy包含一些內置的命令,它可以用來爲項目。要查看可用命令的列表,請使用以下命令: \n \u003c/div\u003e \n \u003cpre\u003escrapy -h\r\u003c/pre\u003e \n \u003cdiv\u003e\n 當運行上面的命令,Scrapy將顯示如下面所列出可用命令的列表: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e fetch:\u0026nbsp;它使用Scrapy\u0026nbsp;downloader\u0026nbsp;提取的\u0026nbsp;URL。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e runspider:\u0026nbsp;它用於而無需創建一個項目運行自行包含蜘蛛(spider)。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e settings:\u0026nbsp;它規定了項目的設定值。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e shell:\u0026nbsp;這是一個給定URL的一個交互式模塊。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e startproject:\u0026nbsp;它創建了一個新的 Scrapy\u0026nbsp;項目。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e version:\u0026nbsp;它顯示Scrapy版本。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e view:\u0026nbsp;它使用Scrapy\u0026nbsp;downloader\u0026nbsp;提取\u0026nbsp;URL並顯示在瀏覽器中的內容。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 一些項目相關的命令,如下: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e crawl:\u0026nbsp;它是用來使用蜘蛛抓取數據; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e check:\u0026nbsp;它檢查項目並由\u0026nbsp;crawl\u0026nbsp;命令返回; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e list:\u0026nbsp;它顯示本項目中可用蜘蛛(spider)的列表; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e edit:\u0026nbsp;可以通過編輯器編輯蜘蛛; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e parse:它通過蜘蛛分析給定的URL; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e bench:\u0026nbsp;它是用來快速運行基準測試(基準講述每分鐘可被Scrapy抓取的頁面數量)。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 自定義項目命令 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 可以在Scrapy項目中通過COMMANDS_MODULE設置構建一個自定義項目命令。 \n \u003c/div\u003e \n \u003cpre\u003eCOMMANDS_MODULE = 'mycmd.commands'\r\u003c/pre\u003e \n \u003cdiv\u003e\n Scrapy命令可以通過使用\u0026nbsp;setup.py\u0026nbsp;文件中的\u0026nbsp;scrapy.commands\u0026nbsp;部分來添加,如下所示: \n \u003c/div\u003e \n \u003cpre\u003efrom setuptools import setup, find_packages\r\n\r\nsetup(name='scrapy-module_demo',\r\n entry_points={\r\n 'scrapy.commands': [\r\n 'cmd_demo=my_module.commands:CmdDemo',\r\n ],\r\n },\r\n)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面的代碼將在setup.py文件添加\u0026nbsp;cmd_demo\u0026nbsp;命令。 \n \u003c/div\u003e \n \u003cp\u003e \u003cbr\u003e \u003c/p\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"14:T317b,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n Spider是負責定義如何遵循通過網站的鏈接並提取網頁中的信息的類。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy默認的\u0026nbsp;Spider\u0026nbsp;如下: \n \u003c/div\u003e \n \u003ch3\u003e scrapy.Spider \u003c/h3\u003e \n \u003cdiv\u003e\n 它是所有其他的蜘蛛(spider)都必須繼承的類。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.Spider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示了 scrapy.Spider 類的字段: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 字段 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e name\u003cbr\u003e 這是\u0026nbsp;spider\u0026nbsp;的名字 \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e allowed_domains\u003cbr\u003e \n \u003cdiv\u003e\n 它是允許\u0026nbsp;spider\u0026nbsp;抓取域名稱的列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e start_urls\u003cbr\u003e \n \u003cdiv\u003e\n 這是供以後蜘蛛將開始抓取的URL列表的根 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e custom_settings\u003cbr\u003e \n \u003cdiv\u003e\n 這些設置在蜘蛛運行時會從項目範圍內覆蓋配置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e crawler\u003cbr\u003e \n \u003cdiv\u003e\n 它是鏈接到 spider 實例綁定的 Crawler 對象的屬性 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e settings\u003cbr\u003e \n \u003cdiv\u003e\n 這些是運行一個\u0026nbsp;spider\u0026nbsp;的設置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e logger\u003cbr\u003e \n \u003cdiv\u003e\n 它是用來發送日誌消息的 python 記錄器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 8 \u003c/td\u003e \n \u003ctd\u003e from_crawler(crawler,*args,**kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它是由\u0026nbsp;spider\u0026nbsp;創建的一個類方法。參數是: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e crawler:\u0026nbsp;抓取工具到\u0026nbsp;spider\u0026nbsp;實例將被綁定; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e args(list):\u0026nbsp;這些參數傳遞給方法:\u0026nbsp;_init_(); \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e kwargs(dict):\u0026nbsp;這些關鍵字參數傳遞給方法:\u0026nbsp;_init_(). \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 9 \u003c/td\u003e \n \u003ctd\u003e start_requests()\u003cbr\u003e \n \u003cdiv\u003e\n 如果不指定特定的URL,蜘蛛會打開抓取,Scrapy調用start_requests()方法 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 10 \u003c/td\u003e \n \u003ctd\u003e make_requests_from_url(url)\u003cbr\u003e \n \u003cdiv\u003e\n 它是用於將URL網址轉換爲請求方法 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 11 \u003c/td\u003e \n \u003ctd\u003e parse(response)\u003cbr\u003e \n \u003cdiv\u003e\n 這個方法處理響應並返回廢棄數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 12 \u003c/td\u003e \n \u003ctd\u003e log(message[,level,component])\u003cbr\u003e \n \u003cdiv\u003e\n 這個方法會通過蜘蛛發送日誌記錄信息 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 13 \u003c/td\u003e \n \u003ctd\u003e closed(reason)\u003cbr\u003e \n \u003cdiv\u003e\n 這種方法在當蜘蛛關閉時調用 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e Spider參數 \u003c/h2\u003e \n \u003cdiv\u003e\n Spider\u0026nbsp;參數用於指定起始URL和使用帶有-a選項的抓取命令來傳遞,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003escrapy crawl first_scrapy -a group = accessories\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的代碼示例顯示蜘蛛是如何接收參數的: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\n\r\nclass FirstSpider(scrapy.Spider):\r\n name = \"first\"\r\n\r\n def __init__(self, group=None, *args, **kwargs):\r\n super(FirstSpider, self).__init__(*args, **kwargs)\r\n self.start_urls = [\"http://www.yiibai.com/group/%s\" % group]\r\u003c/pre\u003e \n \u003ch2\u003e 通用Spider \u003c/h2\u003e \n \u003cp\u003e 您可以使用通用蜘蛛來創建子類蜘蛛。他們的目的是要根據一定的規則來提取所有在網站上的所有鏈接的數據。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cdiv\u003e\n 我們假設項目有以下的字段: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.item import Item, Field\r\n\t\r\nclass First_scrapyItem(scrapy.Item):\r\n product_title = Field()\r\n product_link = Field()\r\n product_description = Field()\r\u003c/pre\u003e \n \u003ch2\u003e CrawlSpider \u003c/h2\u003e \n \u003cdiv\u003e\n CrawlSpider定義了一套規律可循的聯繫,並取消多個頁面。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.CrawlSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 以下是CrawlSpider類的屬性: \n \u003c/div\u003e \n \u003ch3\u003e rules \u003c/h3\u003e \n \u003cdiv\u003e\n 這是規則對象的列表,它定義了爬網程序如何抓取下面的鏈接。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 下面的表顯示了CrawlSpider類的規則: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 規則和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e LinkExtractor\u003cbr\u003e \n \u003cdiv\u003e\n 它指定蜘蛛如何跟隨鏈接和提取數據; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e callback\u003cbr\u003e \n \u003cdiv\u003e\n 它是在每一頁提取之後被調用;\u0026nbsp; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e follow\u003cbr\u003e \n \u003cdiv\u003e\n 它指定是否繼續跟蹤鏈接; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch3\u003e parse_start_url(response) \u003c/h3\u003e \n \u003cp\u003e 它通過允許解析初步迴應返回項目或請求對象。 \u003c/p\u003e \n \u003cp\u003e 注意:\u0026nbsp;請務必重命名等函數解析而不是編寫規則,因爲解析函數用於CrawlSpider來實現它的邏輯。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cp\u003e 讓我們看看下面的例子開始演示蜘蛛爬行\u0026nbsp;example.com 首頁,使用\u0026nbsp;parse_items 方法收集所有頁面上的鏈接和詞組: \u003c/p\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.spiders import CrawlSpider, Rule\r\nfrom scrapy.linkextractors import LinkExtractor\r\n\r\nclass DemoSpider(CrawlSpider):\r\n name = \"demo\"\r\n allowed_domains = [\"www.yiibai.com\"]\r\n start_urls = [\"http://www.yiibai.com\"]\r\n\r\n rules = (\r\n Rule(LinkExtractor(allow =(), restrict_xpaths = (\"//div[@class = 'next']\",)), callback = \"parse_item\", follow = True),\r\n )\r\n\r\n def parse_item(self, response):\r\n item = DemoItem()\r\n item[\"product_title\"] = response.xpath(\"a/text()\").extract()\r\n item[\"product_link\"] = response.xpath(\"a/@href\").extract()\r\n item[\"product_description\"] = response.xpath(\"div[@class='desc']/text()\").extract()\r\n return items\r\u003c/pre\u003e \n \u003ch2\u003e XMLFeedSpider \u003c/h2\u003e \n \u003cdiv\u003e\n 它是從XML的Feed提取並遍歷節點的蜘蛛的基類。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.XMLFeedSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下表顯示了用於設置iterator和標記名稱的類屬性: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 屬性和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e iterator\u003cbr\u003e \n \u003cdiv\u003e\n 它定義將要使用的迭代器。它可以是iternodes,HTML或XML。默認爲:iternodes \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e itertag\u003cbr\u003e \n \u003cdiv\u003e\n 它使用節點名稱的字符串進行迭代 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e namespaces\u003cbr\u003e \n \u003cdiv\u003e\n 它是由(prefix,\u0026nbsp;uri)元組使用register_namespace()方法自動註冊命名空間的列表中定義 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e adapt_response(response)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收響應,並儘快在開始解析之前從蜘蛛中間件修改響應體 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e parse_node(response,selector)\u003cbr\u003e 它接收到響應和選擇器,在每個節點匹配提供標籤名時調用\u003cbr\u003e \n \u003cdiv\u003e\n 注意:如果不重寫此方法,蜘蛛將不起作用 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e process_results(response,results)\u003cbr\u003e \n \u003cdiv\u003e\n 它由蜘蛛返回結果和響應列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e CSVFeedSpider \u003c/h2\u003e \n \u003cdiv\u003e\n 它通過它的每行的迭代,收到一個CSV文件作爲響應,並調用\u0026nbsp;parse_row()\u0026nbsp;方法。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.CSVFeedSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下表顯示了可設置關於CSV文件的選項: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 選項及說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e delimiter\u003cbr\u003e \n \u003cdiv\u003e\n 它是包含每個字段使用逗號(「,」)分隔的字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e quotechar\u003cbr\u003e \n \u003cdiv\u003e\n 這是一個包含每個字段使用引號('\"')字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e headers\u003cbr\u003e \n \u003cdiv\u003e\n 它是一個可從中可以提取字段語句的列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e parse_row(response,row)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收一個響應,並每一行使用報頭鍵 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cp\u003e CSVFeedSpider 示例: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.spiders import CSVFeedSpider\r\nfrom demoproject.items import DemoItem\r\n\r\nclass DemoSpider(CSVFeedSpider):\r\n name = \"demo\"\r\n allowed_domains = [\"www.yiibai.com\"]\r\n start_urls = [\"http://www.yiibai.com/feed.csv\"]\r\n delimiter = \";\"\r\n quotechar = \"'\"\r\n headers = [\"product_title\", \"product_link\", \"product_description\"]\r\n\r\n def parse_row(self, response, row):\r\n self.logger.info(\"This is row: %r\", row)\r\n\r\n item = DemoItem()\r\n item[\"product_title\"] = row[\"product_title\"]\r\n item[\"product_link\"] = row[\"product_link\"]\r\n item[\"product_description\"] = row[\"product_description\"]\r\n return item\r\u003c/pre\u003e \n \u003ch2\u003e SitemapSpider \u003c/h2\u003e \n \u003cp\u003e 站點地圖(\u003ca href=\"http://www.sitemaps.org/\"\u003esitemap\u003c/a\u003e)幫助蜘蛛通過 robots.txt 的定位網址並抓取網站。它有以下類: \u003c/p\u003e \n \u003cpre\u003eclass scrapy.spiders.SitemapSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示了SitemapSpider的字段: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 字段及說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e sitemap_urls\u003cbr\u003e \n \u003cdiv\u003e\n 要抓取指向網站地圖的URL列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e sitemap_rules\u003cbr\u003e \n \u003cdiv\u003e\n 這是一個元組列表\u0026nbsp;(regex,\u0026nbsp;callback)\u0026nbsp;,其中,正則表達式是正則表達式,回調是用來處理的URL匹配的正則表達式 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e sitemap_follow\u003cbr\u003e \n \u003cdiv\u003e\n 這是網站地圖的正則表達式的跟蹤列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e sitemap_alternate_links\u003cbr\u003e \n \u003cdiv\u003e\n 指定要跟蹤一個URL備用鏈路 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cp\u003e SitemapSpider 示例: \u003c/p\u003e \n \u003cdiv\u003e\n 下面是\u0026nbsp;SitemapSpider\u0026nbsp;處理所有的網址: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/sitemap.xml\"]\r\n\r\n def parse(self, response):\r\n # You can scrap items here\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面是\u0026nbsp;SitemapSpider\u0026nbsp;處理某些URL與回調: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/sitemap.xml\"]\r\n rules = [\r\n (\"/item/\", \"parse_item\"),\r\n (\"/group/\", \"parse_group\"),\r\n ]\r\n\r\n def parse_item(self, response):\r\n # you can scrap item here\r\n\r\n def parse_group(self, response):\r\n # you can scrap group here \u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 下面的代碼顯示了跟蹤站點地圖,在 robots.txt 中的網址有\u0026nbsp;/sitemap_company: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/robots.txt\"]\r\n rules = [\r\n (\"/company/\", \"parse_company\"),\r\n ]\r\n sitemap_follow = [\"/sitemap_company\"]\r\n\r\n def parse_company(self, response):\r\n # you can scrap company here\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您甚至可以將\u0026nbsp;SitemapSpider\u0026nbsp;與其他網址相結合如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/robots.txt\"]\r\n rules = [\r\n (\"/company/\", \"parse_company\"),\r\n ]\r\n\r\n other_urls = [\"http://www.yiibai.com/contact-us\"]\r\n\r\n def start_requests(self):\r\n requests = list(super(DemoSpider, self).start_requests())\r\n requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]\r\n return requests\r\n\r\n def parse_company(self, response):\r\n # you can scrap company here...\r\n\t\t\r\n def parse_other(self, response):\r\n # you can scrap other here...\u003c/pre\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"15:T155a,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n 當刮取網頁中的數據,需要通過使用XPath或CSS表達式來實現選擇器機制提取HTML源代碼的某些部分。選擇器是在Python語言的XML和LXML庫建成的 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n 我們使用下面的代碼片段在本章中來定義選擇器不同的概念: \n \u003c/div\u003e \n \u003cpre\u003e\u0026lt;html\u0026gt;\r\n \u0026lt;head\u0026gt;\r\n \u0026lt;title\u0026gt;My Website\u0026lt;/title\u0026gt;\r\n \u0026lt;/head\u0026gt;\r\n \u0026lt;body\u0026gt;\r\n \u0026lt;span\u0026gt;Scrapy Hello world\u0026lt;/span\u0026gt;\r\n \u0026lt;div class='links'\u0026gt;\r\n \u0026lt;a href='one.html'\u0026gt;Link 1\u0026lt;img src='image1.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;a href='two.html'\u0026gt;Link 2\u0026lt;img src='image2.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;a href='three.html'\u0026gt;Link 3\u0026lt;img src='image3.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;/div\u0026gt;\r\n \u0026lt;/body\u0026gt;\r\n\u0026lt;/html\u0026gt;\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 構造選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 可以通過\u0026nbsp;text\u0026nbsp;或\u0026nbsp;TextResponse\u0026nbsp;對象構造選擇器類的實例。根據所提供的輸入類型,選擇器選擇以下規則: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.selector import Selector\r\nfrom scrapy.http import HtmlResponse\r\u003c/pre\u003e \n \u003cdiv\u003e\n 使用上面的代碼,可以從文本建構如下: \n \u003c/div\u003e \n \u003cpre\u003eSelector(text=body).xpath('//span/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示的結果爲: \n \u003c/div\u003e \n \u003cpre\u003e[u'Hello world!!!']\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以從響應構建: \n \u003c/div\u003e \n \u003cpre\u003eresponse = HtmlResponse(url='http://yiibai.com', body=body)\r\nSelector(response=response).xpath('//span/text()').extract()\r\u003c/pre\u003e \n \u003cp\u003e 它顯示的結果爲: \u003c/p\u003e \n \u003cpre\u003e[u'Hello world!!!']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 使用上面的示例代碼片段,您可以構建XPath選擇\u0026nbsp;title\u0026nbsp;標籤定義的標題文本,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.selector.xpath('//title/text()')\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 現在,您可以通過使用 .extract()方法提取文本數據,如下所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//title/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將產生結果如下: \n \u003c/div\u003e \n \u003cpre\u003e[u'My Website']\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示所有元素的名稱,如下所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//div[@class=\"links\"]/a/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它提供的元素顯示如下: \n \u003c/div\u003e \n \u003cpre\u003eLink 1\r\nLink 2\r\nLink 3\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如果要提取的第一個元素,那麼使用\u0026nbsp;.extract_first()方法,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//div[@class=\"links\"]/a/text()').extract_first()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將顯示元素爲: \n \u003c/div\u003e \n \u003cpre\u003eLink 1\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 嵌套選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 使用上面的代碼,通過使用.xpath()方法可以嵌套選擇器來顯示頁面的鏈接和圖像源,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003elinks = response.xpath('//a[contains(@href, \"image\")]')\r\nfor index, link in enumerate(links):\r\n args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())\r\n print 'The link %d pointing to url %s and image %s' % args\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將顯示的結果爲: \n \u003c/div\u003e \n \u003cpre\u003eLink 1 pointing to url [u'one.html'] and image [u'image1.jpg']\r\nLink 2 pointing to url [u'two.html'] and image [u'image2.jpg']\r\nLink 3 pointing to url [u'three.html'] and image [u'image3.jpg']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用正則表達式選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e Scrapy\u0026nbsp;允許使用\u0026nbsp;.re()\u0026nbsp;方法正則表達式來提取數據。從上面的HTML代碼中可提取圖像名稱,如下圖所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//a[contains(@href, \"image\")]/text()').re(r'Name:\\s*(.*)')\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面一行代碼顯示圖像的名稱爲: \n \u003c/div\u003e \n \u003cpre\u003e[u'Link 1',\r\n u'Link 2',\r\n u'Link 3']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 用相對的XPaths \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 當您使用XPaths,它是從 / 開始工作的,嵌套選擇器和XPath都關聯到文件的絕對路徑,而不是選擇器的相對路徑。 \u003c/p\u003e \n \u003cdiv\u003e\n 如果想提取\u0026lt;p\u0026gt;元素,那麼首先獲得所有 div 元素: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;mydiv = response.xpath('//div')\r\u003c/pre\u003e \n \u003cp\u003e 接下來,可以在裏面提取所有 'P' 元素,在XPath前綴加上一個句點 .//p ,如下圖所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;for p in mydiv.xpath('.//p').extract()\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用EXSLT擴展 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e EXSLT是一個社區它發出擴展XML文檔轉換爲XHTML文檔XSLT(可擴展樣式表語言轉換)。可以使用 EXSLT 擴展與 XPath 表達式來註冊名稱空間,如下列表中所示: \u003c/p\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 前綴用法 \n \u003c/div\u003e \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 命名空間 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e re\u003cbr\u003e \n \u003cdiv\u003e\n 正則表達式 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003ca href=\"http://exslt.org/regexp/index.html\"\u003ehttp://exslt.org/regular-expressions\u003c/a\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e set\u003cbr\u003e \n \u003cdiv\u003e\n 集合操作 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003ca href=\"http://exslt.org/set/index.html\"\u003ehttp://exslt.org/sets\u003c/a\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 您可以檢查在上一節中使用正則表達式提取數據的代碼格式。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 有一些關於 XPath 的提示,使用 XPath 與 Scrapy 選擇器時非常有用。欲瞭解更多信息,請點擊此 \n \u003ca href=\"https://www.yiibai.com/scrapy/xpth_tips.html\"\u003e鏈接\u003c/a\u003e。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"16:T841,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n Scrapy進程可通過使用蜘蛛提取來自網頁中的數據。Scrapy使用Item類生成輸出對象用於收刮數據。 \n\u003c/div\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 聲明項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cdiv\u003e\n 如下圖所示,您可以通過使用字段對象和類定義語法聲明項目: \n\u003c/div\u003e \n\u003cpre\u003eimport scrapy\r\nclass MyProducts(scrapy.Item):\r\n productName = Field()\r\n productLink = Field()\r\n imageURL = Field()\r\n price = Field()\r\n size = Field()\r\u003c/pre\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 項目字段 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cp\u003e 項目字段用於顯示每個字段的元數據。字段對象上的值沒有限制,可訪問元數據的鍵不包含的元數據的任何引用列表。字段對象用於指定所有字段元數據,您可以根據項目您的要求指定任何其他字段鍵。字段對象可以通過使用 Item.fields 屬性進行訪問。 \u003c/p\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 使用項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cp\u003e 當在使用項目工作時,可以定義一些常用功能。欲瞭解更多信息,請點擊此\u003ca href=\"https://www.yiibai.com/scrapy/working_with_items.html\"\u003e鏈接\u003c/a\u003e。 \u003c/p\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 擴展項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cdiv\u003e\n 項目可以從原始項目的子類聲明進行擴展。\u0026nbsp;例如: \n\u003c/div\u003e \n\u003cpre\u003eclass MyProductDetails(Product):\r\n original_rate = scrapy.Field(serializer=str)\r\n discount_rate = scrapy.Field()\r\u003c/pre\u003e \n\u003cdiv\u003e\n 可以通過使用現有的字段元數據添加更多的值,或者改變現有值來擴展,如下面的代碼: \n\u003c/div\u003e \n\u003cpre\u003eclass MyProductPackage(Product):\r\n name = scrapy.Field(Product.fields['name'], serializer=serializer_demo)\r\u003c/pre\u003e \n\u003ch2\u003e 項目對象 \u003c/h2\u003e \n\u003cdiv\u003e\n Item\u0026nbsp;對象可以通過使用以下類,它從指定的參數提供新的初始化項目: \n\u003c/div\u003e \n\u003cpre\u003eclass scrapy.item.Item([arg])\u0026nbsp;\u003c/pre\u003e \n\u003cp\u003e Item\u0026nbsp;提供了一個構造函數的副本,並由在\u0026nbsp;fields\u0026nbsp;中的項目提供額外的屬性。\u0026nbsp; \u003c/p\u003e \n\u003ch2\u003e 字段對象 \u003c/h2\u003e \n\u003cdiv\u003e\n 字段對象可以通過使用下面類中的Field類,不發出附加處理或屬性來指定: \n\u003c/div\u003e \n\u003cpre\u003eclass scrapy.item.Field([arg])\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"17:T4449,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n 項目加載器提供了一個方便的方式來填補從網站上刮取的項目。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 聲明項目加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器的聲明類:Items。例如: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.loader import ItemLoader\r\nfrom scrapy.loader.processors import TakeFirst, MapCompose, Join\r\n\r\nclass DemoLoader(ItemLoader):\r\n\r\n default_output_processor = TakeFirst()\r\n\r\n title_in = MapCompose(unicode.title)\r\n title_out = Join()\r\n\r\n size_in = MapCompose(unicode.strip)\r\n\r\n # you can continue scraping here\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 在上面的代碼可以看到,輸入處理器使用 _id 作爲後綴以及輸出處理器聲明使用_out 作爲後綴聲明。ItemLoader.default_input_processor\u0026nbsp;和\u0026nbsp;ItemLoader.default_output_processor\u0026nbsp;屬性用於聲明默認輸入/輸出處理器。 \u003c/p\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用項目加載器來填充項目 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 要使用項目加載器,先用類似字典的對象,或項目使用\u0026nbsp;Loader.default_item_class\u0026nbsp;屬性指定\u0026nbsp;Item\u0026nbsp;類實例化。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以使用選擇器來收集值到項目加載器。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以在同一項目字段中添加更多的值,項目加載器將使用相應的處理程序來添加這些值。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 下面的代碼演示項目是如何使用項目加載器來填充: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.loader import ItemLoader\r\nfrom demoproject.items import Demo\r\n\r\ndef parse(self, response):\r\n l = ItemLoader(item = Product(), response = response)\r\n l.add_xpath(\"title\", \"//div[@class='product_title']\")\r\n l.add_xpath(\"title\", \"//div[@class='product_name']\")\r\n l.add_xpath(\"desc\", \"//div[@class='desc']\")\r\n l.add_css(\"size\", \"div#size]\")\r\n l.add_value(\"last_updated\", \"yesterday\")\r\n return l.load_item()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如上圖所示,有兩種不同的XPath,使用\u0026nbsp;add_xpath()方法從標題(title)字段提取: \n \u003c/div\u003e \n \u003cpre\u003e1. //div[@class=\"product_title\"] \r\n\r\n2. //div[@class=\"product_name\"]\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 此後,類似請求用於內容描述(desc)字段。size數據使用\u0026nbsp;add_css()方法提取和last_updated\u0026nbsp;使用add_value()方法使用值「yesterday」來填充。 \u003c/p\u003e \n \u003cdiv\u003e\n 完成所有收集數據的,調用\u0026nbsp;ItemLoader.load_item()\u0026nbsp;方法返回填充並使用\u0026nbsp;add_xpath(),add_css()和\u0026nbsp;dadd_value()方法提取數據項。 \n \u003c/div\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 輸入和輸出處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 一個項目加載器的各個字段包含一個輸入處理器和一個輸出處理器。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 當提取數據時,輸入處理器處理結果,交將結果存儲在數據加載器。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 接下來,收集數據後,調用\u0026nbsp;ItemLoader.load_item()\u0026nbsp;方法來獲得\u0026nbsp;Item\u0026nbsp;對象。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 最後,指定輸出處理器到該項目的結果。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 下面的代碼演示針對特定字段如何調用輸入和輸出處理器: \n \u003c/div\u003e \n \u003cpre\u003el = ItemLoader(Product(), some_selector)\r\nl.add_xpath(\"title\", xpath1) # [1]\r\nl.add_xpath(\"title\", xpath2) # [2]\r\nl.add_css(\"title\", css) # [3]\r\nl.add_value(\"title\", \"demo\") # [4]\r\nreturn l.load_item() # [5]\r\u003c/pre\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e 第1行:\u0026nbsp;標題(title)的數據是從xpath1提取並通過輸入處理器,其結果被收集並存儲在\u0026nbsp;ItemLoader\u0026nbsp;中。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第2行:\u0026nbsp;同樣地,標題(title)從xpath2提取並通過相同的輸入處理器,其結果收集的數據加到[1]中。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第3行:\u0026nbsp;標題(title)被從css選擇萃取和通過相同的輸入處理器傳遞並將收集的數據結果加到[1]及[2]。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第4行:\u0026nbsp;接着,將「demo」值分配並傳遞到輸入處理器。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第5行:\u0026nbsp;最後,數據是從所有字段內部收集並傳遞給輸出處理器,最終值將分配給項目。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 聲明輸入和輸出處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 輸入和輸出的處理器在項目加載器(ItemLoader\u0026nbsp;)定義聲明。除此之外,它們還可以在項目字段的元數據指定。 \u003c/p\u003e \n \u003cp\u003e 例如: \u003c/p\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.loader.processors import Join, MapCompose, TakeFirst\r\nfrom w3lib.htmll import remove_tags\r\n\r\ndef filter_size(value):\r\n if value.isdigit():\r\n return value\r\n\r\nclass Item(scrapy.Item):\r\n name = scrapy.Field(\r\n input_processor = MapCompose(remove_tags),\r\n output_processor = Join(),\r\n )\r\n size = scrapy.Field(\r\n input_processor = MapCompose(remove_tags, filter_price),\r\n output_processor = TakeFirst(),\r\n )\r\u003c/pre\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader import ItemLoader\r\n\u0026gt;\u0026gt;\u0026gt; il = ItemLoader(item=Product())\r\n\u0026gt;\u0026gt;\u0026gt; il.add_value('title', [u'Hello', u'\u0026lt;strong\u0026gt;world\u0026lt;/strong\u0026gt;'])\r\n\u0026gt;\u0026gt;\u0026gt; il.add_value('size', [u'\u0026lt;span\u0026gt;100 kg\u0026lt;/span\u0026gt;'])\r\n\u0026gt;\u0026gt;\u0026gt; il.load_item()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示的輸出結果如下: \n \u003c/div\u003e \n \u003cpre\u003e{'title': u'Hello world', 'size': u'100 kg'}\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 項目加載器上下文 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器上下文是輸入和輸出的處理器中共享的任意鍵值的字典。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如,假設有一個函數parse_length: \n \u003c/div\u003e \n \u003cpre\u003edef parse_length(text, loader_context):\r\n unit = loader_context.get('unit', 'cm')\r\n # You can write parsing code of length here \r\n return parsed_length\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 通過接收loader_context參數,它告訴項目加載器可以收到項目加載器上下文。有幾種方法可以改變項目加載器上下文的值: \u003c/p\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 修改當前的活動項目加載器上下文: \n \u003c/div\u003e \u003cpre\u003eloader = ItemLoader (product)\r\nloader.context [\"unit\"] = \"mm\"\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 在項目加載器實例中修改: \n \u003c/div\u003e \u003cpre\u003eloader = ItemLoader(product, unit=\"mm\")\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 在加載器項目聲明與項目加載器上下文實例輸入/輸出處理器中修改: \n \u003c/div\u003e \u003cpre\u003eclass ProductLoader(ItemLoader):\r\n length_out = MapCompose(parse_length, unit=\"mm\")\r\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e ItemLoader對象 \u003c/h2\u003e \n \u003cdiv\u003e\n 它是一個對象,它返回一個新項加載器到填充給定項目。它有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示 ItemReader 對象的參數: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 參數 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e item\u003cbr\u003e 它是通過\u0026nbsp;calling\u0026nbsp;add_xpath(),\u0026nbsp;add_css()\u0026nbsp;或\u0026nbsp;add_value()的填充項 \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e selector\u003cbr\u003e \n \u003cdiv\u003e\n 它用來從網站提取數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e response\u003cbr\u003e \n \u003cdiv\u003e\n 它是用\u0026nbsp;default_selector_class\u0026nbsp;來構造選擇器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 下表顯示項目加載器(ItemLoader)對象的方法: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 方法 \u0026amp; 描述 \u003c/th\u003e \n \u003cth\u003e 示例 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e get_value(value, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 由一個給定的處理器和關鍵字參數,該值在getValue()方法處理 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e \u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import TakeFirst\r\n \u0026gt;\u0026gt;\u0026gt; loader.get_value(u'title: demoweb', TakeFirst(), unicode.upper, re='title: (.+)')\r\n 'DEMOWEB`\r\n\t\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e add_value(field_name, value, *processors, **kwargs)\u003cbr\u003e 它首先通過get_value傳遞處理值,並增加到字段中 \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.add_value('title', u'DVD')\r\n loader.add_value('colors', [u'black', u'white'])\r\n loader.add_value('length', u'80')\r\n loader.add_value('price', u'2500')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e replace_value(field_name, value, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它用一個新值替換所收集的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.replace_value('title', u'DVD')\r\n loader.replace_value('colors', [u'black', u'white'])\r\n loader.replace_value('length', u'80')\r\n loader.replace_value('price', u'2500')\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e get_xpath(xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它用於由接到的XPath給處理器和關鍵字參數提取unicode字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.get_xpath(\"//div[@class='item-name']\")\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.get_xpath(\"//div[@id='length']\", TakeFirst(), re=\"the length is (.*)\")\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e add_xpath(field_name, xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收XPath提取unicode字符串到字段中 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.add_xpath('name', '//div[@class=\"item-name\"]')\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.add_xpath('length', '//div[@id=\"length\"]', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e replace_xpath(field_name, xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它使用XPath取換了從網站收集的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.replace_xpath('name', '//div[@class=\"item-name\"]')\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.replace_xpath('length', '//div[@id=\"length\"]', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e get_css(css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收用於提取unicode字符串的CSS選擇器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.get_css(\"div.item-name\")\r\n loader.get_css(\"div#length\", TakeFirst(), re=\"the length is (.*)\")\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 8 \u003c/td\u003e \n \u003ctd\u003e add_css(field_name, css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它類似於add_value()方法,它增加CSS選擇器到字段中 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.add_css('name', 'div.item-name')\r\n loader.add_css('length', 'div#length', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 9 \u003c/td\u003e \n \u003ctd\u003e replace_css(field_name, css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它使用CSS選擇器取代了提取的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.replace_css('name', 'div.item-name')\r\n loader.replace_css('length', 'div#length', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 10 \u003c/td\u003e \n \u003ctd\u003e load_item()\u003cbr\u003e \n \u003cdiv\u003e\n 當收集數據後,這個方法填充收集到數據的項目並返回 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e def parse(self, response):\r\n l = ItemLoader(item=Product(), response=response)\r\n l.add_xpath('title', '//div[@class=\"product_title\"]')\r\n loader.load_item()\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 11 \u003c/td\u003e \n \u003ctd\u003e nested_xpath(xpath)\u003cbr\u003e \n \u003cdiv\u003e\n 它是通過XPath選擇器來創建嵌套加載器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader = ItemLoader(item=Item())\r\n loader.add_xpath('social', 'a[@class = \"social\"]/@href')\r\n loader.add_xpath('email', 'a[@class = \"email\"]/@href')\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 12 \u003c/td\u003e \n \u003ctd\u003e nested_css(css)\u003cbr\u003e \n \u003cdiv\u003e\n 它被用來創建一個CSS選擇器嵌套加載器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader = ItemLoader(item=Item())\r\n loader.add_css('social', 'a[@class = \"social\"]/@href')\r\n loader.add_css('email', 'a[@class = \"email\"]/@href')\t\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 下表顯示項目加載器對象的屬性: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 屬性 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e item\u003cbr\u003e \n \u003cdiv\u003e\n 它是項目加載器進行解析的對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e context\u003cbr\u003e \n \u003cdiv\u003e\n 這是項目加載器是活躍的當前上下文 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e default_item_class\u003cbr\u003e \n \u003cdiv\u003e\n 如果在構造沒有給出,它用來表示項 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e default_input_processor\u003cbr\u003e \n \u003cdiv\u003e\n 不指定輸入處理器中的字段,只有一個用於其默認輸入處理器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e default_output_processor\u003cbr\u003e \n \u003cdiv\u003e\n 不指定輸出處理器中的字段,只有一個用於其默認的輸出處理器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e default_selector_class\u003cbr\u003e \n \u003cdiv\u003e\n 如果它沒有在構造給定,它是使用來構造選擇器的一個類 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e selector\u003cbr\u003e \n \u003cdiv\u003e\n 它是一個用來從站點提取數據的對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 嵌套加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 這是使用從文檔解析分段的值來創建嵌套加載器。如果不創建嵌套裝載器,需要爲您想提取的每個值指定完整的XPath或CSS。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如,假設要從一個標題頁中提取數據: \n \u003c/div\u003e \n \u003cpre\u003e\u0026lt;header\u0026gt;\r\n \u0026lt;a class=\"social\" href=\"http://facebook.com/whatever\"\u0026gt;facebook\u0026lt;/a\u0026gt;\r\n \u0026lt;a class=\"social\" href=\"http://twitter.com/whatever\"\u0026gt;twitter\u0026lt;/a\u0026gt;\r\n \u0026lt;a class=\"email\" href=\"mailto:someone@example.com\"\u0026gt;send mail\u0026lt;/a\u0026gt;\r\n\u0026lt;/header\u0026gt;\r\u003c/pre\u003e \n \u003cdiv\u003e\n 接下來,您可以通過添加相關的值到頁眉來創建頭選擇器嵌套裝載器: \n \u003c/div\u003e \n \u003cpre\u003eloader = ItemLoader(item=Item())\r\nheader_loader = loader.nested_xpath('//header')\r\nheader_loader.add_xpath('social', 'a[@class = \"social\"]/@href')\r\nheader_loader.add_xpath('email', 'a[@class = \"email\"]/@href')\r\nloader.load_item()\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 重用和擴展項目加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器的設計以緩解維護,當要獲取更多的蜘蛛時項目變成一個根本的問題。 \n \u003c/div\u003e \n \u003cp\u003e 舉例來說,假設一個網站自己的產品名稱是由三條短線封閉的(例如:\u0026nbsp;---DVD---)。\u0026nbsp;您可以通過重複使用默認產品項目加載器,如果你不希望它在最終產品名稱所示,下面的代碼刪除這些破折號: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.loader.processors import MapCompose\r\nfrom demoproject.ItemLoaders import DemoLoader\r\n\r\ndef strip_dashes(x):\r\n return x.strip('-')\r\n\r\nclass SiteSpecificLoader(DemoLoader):\r\n title_in = MapCompose(strip_dashes, DemoLoader.title_in)\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 可用內置處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 以下是一些常用的內置處理器: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.Identity \u003c/p\u003e \n \u003cdiv\u003e\n 它返回原始的值而並不修改它。\u0026nbsp;例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import Identity\r\n\u0026gt;\u0026gt;\u0026gt; proc = Identity()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\n['a', 'b', 'c']\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.TakeFirst \u003c/p\u003e \n \u003cdiv\u003e\n 它返回一個值來自收到列表的值即非空/非null值。\u0026nbsp;例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import TakeFirst\r\n\u0026gt;\u0026gt;\u0026gt; proc = TakeFirst()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['', 'a', 'b', 'c'])\r\n'a'\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.Join(separator = u' ') \u003c/p\u003e \n \u003cdiv\u003e\n 它返回附連到分隔符的值。默認的分隔符是\u0026nbsp;u'',這相當於於\u0026nbsp;u'\u0026nbsp;'.join\u0026nbsp;的功能。例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import Join\r\n\u0026gt;\u0026gt;\u0026gt; proc = Join()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\nu'a b c'\r\n\u0026gt;\u0026gt;\u0026gt; proc = Join('\u0026lt;br\u0026gt;')\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\nu'a\u0026lt;br\u0026gt;b\u0026lt;br\u0026gt;c'\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.SelectJmes(json_path) \u003c/p\u003e \n \u003cdiv\u003e\n 此類查詢使用提供JSON路徑值,並返回輸出。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import SelectJmes, Compose, MapCompose\r\n\u0026gt;\u0026gt;\u0026gt; proc = SelectJmes(\"hello\")\r\n\u0026gt;\u0026gt;\u0026gt; proc({'hello': 'scrapy'})\r\n'scrapy'\r\n\u0026gt;\u0026gt;\u0026gt; proc({'hello': {'scrapy': 'world'}})\r\n{'scrapy': 'world'}\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面是一個查詢通過導入JSON值的代碼: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; import json\r\n\u0026gt;\u0026gt;\u0026gt; proc_single_json_str = Compose(json.loads, SelectJmes(\"hello\"))\r\n\u0026gt;\u0026gt;\u0026gt; proc_single_json_str('{\"hello\": \"scrapy\"}')\r\nu'scrapy'\r\n\u0026gt;\u0026gt;\u0026gt; proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))\r\n\u0026gt;\u0026gt;\u0026gt; proc_json_list('[{\"hello\":\"scrapy\"}, {\"world\":\"env\"}]')\r\n[u'scrapy']\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"18:T18f5,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy\u0026nbsp;shell\u0026nbsp;可用於抓取數據並提示錯誤代碼,而無需使用蜘蛛。\u0026nbsp;Scrapy\u0026nbsp;shell的主要目的是測試所提取的代碼,XPath或CSS表達式。它還用來從中指定刮取數據的網頁。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 配置Shell \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n shell\u0026nbsp;可以通過安裝\u0026nbsp; \n \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e(用於交互式計算)控制檯,它是強大的交互式的Shell,提供自動完成,彩色輸出等功能。 \n \u003c/div\u003e \n \u003cp\u003e 如果您在UNIX平臺上工作,那麼最好安裝 IPython。\u0026nbsp;如果有IPython的無法訪問,您也可以使用\u003ca href=\"http://www.bpython-interpreter.org/\"\u003ebpython\u003c/a\u003e。 \u003c/p\u003e \n \u003cdiv\u003e\n 您可以通過設置\u0026nbsp;SCRAPY_PYTHON_SHELL 環境變量或者在 scrapy.cfg 文件中定義配置\u0026nbsp;Shell,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e[settings]\r\nshell = bpython\r\u003c/pre\u003e \n \u003ch2\u003e 啓動Shell \u003c/h2\u003e \n \u003cdiv\u003e\n Scrapy\u0026nbsp;shell\u0026nbsp;可以用下面的命令來啓動: \n \u003c/div\u003e \n \u003cpre\u003escrapy shell \u0026lt;url\u0026gt;\r\u003c/pre\u003e \n \u003cdiv\u003e\n url 是指定爲需要進行數據抓取的URL \n \u003c/div\u003e \n \u003ch2\u003e 使用Shell \u003c/h2\u003e \n \u003cdiv\u003e\n shell提供一些附加快捷方式和Scrapy對象,如下所述: \n \u003c/div\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 可用快捷方式 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n shell提供可在項目中使用的快捷方式如下: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 快捷方式和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e shelp()\u003cbr\u003e \n \u003cdiv\u003e\n 它提供了可用對象和快捷方式的幫助選項 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e fetch(request_or_url)\u003cbr\u003e \n \u003cdiv\u003e\n 它會從請求或URL的響應收集相關對象可能的更新 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e view(response)\u003cbr\u003e 可以在本地瀏覽器查看特定請求的響應,觀察和正確顯示外部鏈接,追加基本標籤到響應正文。 \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 可用Scrapy對象 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n shell在項目中提供以下可用Scrapy對象: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 對象和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e crawler\u003cbr\u003e \n \u003cdiv\u003e\n 它指定當前爬行對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e spider\u003cbr\u003e \n \u003cdiv\u003e\n 如果對於當前網址沒有蜘蛛,那麼它將通過定義新的蜘蛛處理URL或蜘蛛對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e request\u003cbr\u003e \n \u003cdiv\u003e\n 它指定了最後採集頁面請求對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e response\u003cbr\u003e \n \u003cdiv\u003e\n 它指定了最後採集頁面響應對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e settings\u003cbr\u003e \n \u003cdiv\u003e\n 它提供當前Scrapy設置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n Shell會話示例 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 讓我們試着刮取 scrapy.org 網站,然後開始從 yiibai.com 抓取數據,如下所述: \n \u003c/div\u003e \n \u003cdiv\u003e\n 在繼續之前,我們將首先啓動shell,執行如下面的命令: \n \u003c/div\u003e \n \u003cpre\u003escrapy shell 'http://scrapy.org' --nolog\r\u003c/pre\u003e \n \u003cdiv\u003e\n 當使用上面的URL,Scrapy將顯示可用的對象: \n \u003c/div\u003e \n \u003cpre\u003e[s] Available Scrapy objects:\r\n[s] crawler \r\n[s] item {}\r\n[s] request \r\n[s] response \u0026lt;200 http://scrapy.org\u0026gt;\r\n[s] settings \r\n[s] spider \r\n[s] Useful shortcuts:\r\n[s] shelp() Provides available objects and shortcuts with help option\r\n[s] fetch(req_or_url) Collects the response from the request or URL and associated objects will get update\r\n[s] view(response) View the response for the given request\r\u003c/pre\u003e \n \u003cdiv\u003e\n 接着,對象的工作開始,如下所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; response.xpath('//title/text()').extract_first()\r\nu'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'\r\n\r\n\u0026gt;\u0026gt; fetch(\"http://reddit.com\")\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n[s] item {}\r\n[s] request \r\n[s] response \u0026lt;200 https://www.yiibai.com/\u0026gt;\r\n[s] settings \r\n[s] spider \r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\r\n\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'reddit: the front page of the internet']\r\n\r\n\u0026gt;\u0026gt; request = request.replace(method=\"POST\")\r\n\r\n\u0026gt;\u0026gt; fetch(request)\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n...\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 從Spider檢查響應調用Shell \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 您可以檢查它是由蜘蛛處理的響應,只有期望得到的響應。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\nclass SpiderDemo(scrapy.Spider):\r\n name = \"spiderdemo\"\r\n start_urls = [\r\n \"http://yiibai.com\",\r\n \"http://yiibai.org\",\r\n \"http://yiibai.net\",\r\n ]\r\n\r\n def parse(self, response):\r\n # You can inspect one specific response\r\n if \".net\" in response.url:\r\n from scrapy.shell import inspect_response\r\n inspect_response(response, self)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 正如上面的代碼所示,可以從蜘蛛調用shell,通過使用下面的函數來檢查響應: \n \u003c/div\u003e \n \u003cpre\u003escrapy.shell.inspect_response\r\u003c/pre\u003e \n \u003cdiv\u003e\n 現在運行的蜘蛛,應該會得到如下界面: \n \u003c/div\u003e \n \u003cpre\u003e2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n...\r\n\r\n\u0026gt;\u0026gt; response.url\r\n'http://yiibai.org'\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以使用下面的代碼檢查提取的代碼是否正常工作: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; response.xpath('//div[@class=\"val\"]')\r\nIt displays the output as\r\n[]\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面一行只顯示空白輸出。現在可以調用 shell 來檢查響應,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; view(response)\r\nIt displays the response as\r\nTrue\u003c/pre\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"19:T12ab,"])</script><script>self.__next_f.push([1,"\u003cp\u003eSpider定義從提取數據的初始 \u003cem\u003eURL\u003c/em\u003e,如何遵循分頁鏈接以及如何提取和分析在 \u003cem\u003eitems.py\u003c/em\u003e 定義字段的類。\u003cem\u003eScrapy\u003c/em\u003e 提供了不同類型的蜘蛛,每個都給出了一個具體的目的。\u003c/p\u003e \n\u003cp\u003e在 first_scrapy/spiders 目錄下創建了一個叫作 「first_spider.py」 文件,在這裏可以告訴 \u003cem\u003escrapy\u003c/em\u003e 。要如何查找確切數據,這裏必須要定義一些屬性:\u003c/p\u003e \n\u003cul\u003e \n \u003cli\u003e\u003cp\u003ename: 它定義了蜘蛛的唯一名稱;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003eallowed_domains: 它包含了蜘蛛抓取的基本URL;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003estart-urls: 蜘蛛開始爬行的URL列表;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003eparse(): 這是提取並解析刮下數據的方法;\u003c/p\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cp\u003e下面的代碼演示了蜘蛛代碼的樣子:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e# -*- coding: utf-8 -*-\r\n\r\n# Define here the models for your scraped items\r\n#\r\n# See documentation in:\r\n# http://doc.scrapy.org/en/latest/topics/items.html\r\n\r\nimport scrapy\r\n\r\nclass firstSpider(scrapy.Spider):\r\n name = \"first\"\r\n allowed_domains = [\"yiibai.com\"]\r\n start_urls = [\r\n \"http://www.yiibai.com/scrapy/scrapy_create_project.html\",\r\n \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n ]\r\n\r\n def parse(self, response):\r\n filename = response.url.split(\"/\")[-1]\r\n print 'Curent URL =\u0026gt; ', filename\r\n with open(filename, 'wb') as f:\r\n f.write(response.body)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e執行結果如下所示 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy crawl first\r\n2016-10-03 10:40:10 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 10:40:10 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'first_scrapy'}\r\n2016-10-03 10:40:10 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.logstats.LogStats',\r\n 'scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 10:40:11 [scrapy] INFO: Spider opened\r\n2016-10-03 10:40:11 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_create_project.html\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\nCurent URL =\u0026gt; scrapy_create_project.html\r\nCurent URL =\u0026gt; scrapy_environment.html\r\n2016-10-03 10:40:12 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 10:40:12 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 2, 40, 12, 98000),\r\n 'log_count/DEBUG': 4,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 2, 40, 11, 614000)}\r\n2016-10-03 10:40:12 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1a:Tfa1,"])</script><script>self.__next_f.push([1,"\u003cp\u003e要執行蜘蛛抓取數據,在 \u003cem\u003efirst_scrapy\u003c/em\u003e 目錄中運行以下命令: \u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy crawl first\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e在這裏,\u003cem\u003efirst\u003c/em\u003e 是創建蜘蛛時指定的蜘蛛名稱。\u003c/p\u003e \n\u003cp\u003e當蜘蛛開始抓取後,可以看到如下面的輸出:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy crawl first\r\n2016-10-03 10:40:10 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 10:40:10 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'first_scrapy'}\r\n2016-10-03 10:40:10 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.logstats.LogStats',\r\n 'scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 10:40:11 [scrapy] INFO: Spider opened\r\n2016-10-03 10:40:11 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_create_project.html\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\nCurent URL =\u0026gt; scrapy_create_project.html\r\nCurent URL =\u0026gt; scrapy_environment.html\r\n2016-10-03 10:40:12 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 10:40:12 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 2, 40, 12, 98000),\r\n 'log_count/DEBUG': 4,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 2, 40, 11, 614000)}\r\n2016-10-03 10:40:12 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e正如你在輸出中看到的, 每個URL有一個日誌行,其中(引用:None)表示,網址是起始網址,它沒有引用。接下來,應該看到有兩個名爲 \u003cem\u003escrapy_environment.html\u003c/em\u003e和 \u003cem\u003escrapy_environment.html\u003c/em\u003e 的文件在 first_scrapy 這個目錄中有被創建。\u003cbr\u003e如下所示 -\u003cbr\u003e\u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-3.png\" alt=\"Scrapy執行爬行捉取\"\u003e\u003c/p\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1b:T1bb4,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e \n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u0026lt;head\u0026gt; 元素中的 \u0026lt;title\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e/html/head/title/text(): 這將選擇 \u0026lt;title\u0026gt; 元素中的文本。\u003c/p\u003e \n\u003cp\u003e//td: 這將選擇所有的 \u0026lt;td\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e//div[\u003ca href=\"https://github.com/class\" title=\"@class\" class=\"at-link\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e \n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e方法 \u0026amp; 描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003eextract()\u003c/td\u003e \n \u003ctd\u003e它返回一個unicode字符串以及所選數據\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ere()\u003c/td\u003e \n \u003ctd\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003expath()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ecss()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch2\u003e在Shell中使用選擇器\u003c/h2\u003e \n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\r\n[s] item {}\r\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\r\n[s] spider \u0026lt;firstSpider 'first' at 0x47f9f28\u0026gt;\r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e \n\u003cp\u003e例如:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath('//title')\r\n[\u0026lt;Selector xpath='//title' data=u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title').extract()\r\n[u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()')\r\n[\u0026lt;Selector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').re('(w+):')\r\n[]\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e提取數據\u003c/h2\u003e \n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e \n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e \n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li')\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇描述:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/@href').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\n\r\nclass MyprojectSpider(scrapy.Spider):\r\n name = \"project\"\r\n allowed_domains = [\"dmoz.org\"]\r\n start_urls = [\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\r\n ]\r\n\r\n def parse(self, response):\r\n for sel in response.xpath('//ul/li'):\r\n title = sel.xpath('a/text()').extract()\r\n link = sel.xpath('a/@href').extract()\r\n desc = sel.xpath('text()').extract()\r\n print title, link, desc\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1c:T3db5,"])</script><script>self.__next_f.push([1,"\u003cp\u003e項目(Item)對象是Python中的常規的字典類型。我們可以用下面的語法來訪問類的屬性:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; item = YiibaiItem()\r\n\u0026gt;\u0026gt;\u0026gt; item['title'] = 'sample title'\r\n\u0026gt;\u0026gt;\u0026gt; item['title']\r\n'sample title'\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e添加上述代碼到下面的例子中:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e# -*- coding: utf-8 -*-\r\n\r\n# Define here the models for your scraped items\r\n#\r\n# See documentation in:\r\n# http://doc.scrapy.org/en/latest/topics/items.html\r\n\r\nimport scrapy\r\n\r\n\r\nfrom first_scrapy.items import YiibaiItem\r\n\r\nclass firstSpider(scrapy.Spider):\r\n name = \"first\"\r\n allowed_domains = [\"yiibai.com\"]\r\n start_urls = [\r\n \"http://www.yiibai.com/scrapy/scrapy_create_project.html\",\r\n \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n ]\r\n\r\n def parse(self, response):\r\n # 所有教程名稱及鏈接 ...\r\n for sel in response.xpath('//ul/li'):\r\n item = YiibaiItem()\r\n item['title'] = sel.xpath('a/text()').extract()\r\n item['link'] = sel.xpath('a/@href').extract()\r\n item['desc'] = sel.xpath('text()').extract()\r\n yield item\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e因此,上述蜘蛛的部分輸出結果是:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/python3/'],\r\n 'title': [u'Python3u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/php7/'],\r\n 'title': [u'PHP7u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/excel/'],\r\n 'title': [u'Excelu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/uml/'],\r\n 'title': [u'UML']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/socket/'],\r\n 'title': [u'Socketu7f16u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/radius/'],\r\n 'title': [u'Radiusu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/nodejs/'],\r\n 'title': [u'Node.jsu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/svn/'],\r\n 'title': [u'SVNu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/git/'],\r\n 'title': [u'Gitu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/makefile/'],\r\n 'title': [u'Makefile']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix/'],\r\n 'title': [u'Unix']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix_commands/'],\r\n 'title': [u'Linux/Unixu547du4ee4']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix_system_calls/'],\r\n 'title': [u'Unix/Linuxu7cfbu7edfu8c03u7528']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/shell/'],\r\n 'title': [u'Shell']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/drools/'],\r\n 'title': [u'Droolsu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/linq/'],\r\n 'title': [u'LinQu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/wcf/'],\r\n 'title': [u'WCFu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mysql/'],\r\n 'title': [u'MySQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/plsql/'],\r\n 'title': [u'PL/SQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/postgresql/'],\r\n 'title': [u'PostgreSQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mongodb/'],\r\n 'title': [u'MongoDBu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sqlite/'],\r\n 'title': [u'SQLiteu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/db2/'],\r\n 'title': [u'DB2u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/redis/'],\r\n 'title': [u'Redisu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/memcached/'],\r\n 'title': [u'Memcachedu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/access/'],\r\n 'title': [u'Accessu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sql/'],\r\n 'title': [u'SQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sql_server/'],\r\n 'title': [u'SQL Serveru6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/java/'],\r\n 'title': [u'Java']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/python/'],\r\n 'title': [u'Python']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mysql/'],\r\n 'title': [u'MySQL']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/articles'],\r\n 'title': [u'u6700u65b0u6587u7ae0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/login/byqq'],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ',\r\n u'\r\n ',\r\n u'\r\n',\r\n u'\r\n ',\r\n u'\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n ', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5xa0', u'\u0026amp;amd64\r\n '],\r\n 'link': [u'http://sourceforge.net/projects/pywin32/'],\r\n 'title': [u'pywin32']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5 Python2.7.9 u4ee5u4e0bu7684xa0',\r\n u'xa0u6216u8005u4e0bu8f7du5730u5740uff1axa0',\r\n u' \r\n '],\r\n 'link': [u'https://pip.pypa.io/en/latest/installing/',\r\n u'https://pypi.python.org/pypi/setuptools#files',\r\n u'https://pypi.python.org/pypi/setuptools#files'],\r\n 'title': [u'pip', u'https://pypi.python.org/pypi/setuptools#files', u'xa0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u60a8u53efu4ee5u901au8fc7u4f7fu7528u4ee5u4e0bu547du4ee4u6765u68c0u67e5 pip u7248u672cuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5twisteduff0cu4e0bu8f7du5730u5740 -',\r\n u' \r\n '],\r\n 'link': [u'https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0'],\r\n 'title': [u'https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5xa0zope u63a5u53e3uff1a',\r\n u'xa0u9009u62e9u5012u6570u7b2cu4e8cu4e2axa0',\r\n u'xa0',\r\n u'\r\n '],\r\n 'link': [u'https://pypi.python.org/pypi/zope.interface/4.1.0',\r\n u'https://pypi.python.org/packages/2.7/z/zope.interface/zope.interface-4.1.0.win32-py2.7.exe#md5=c0100a3cd6de6ecc3cd3b4d678ec7931'],\r\n 'title': [u'https://pypi.python.org/pypi/zope.interface/4.1.0',\r\n u'zope.interface-4.1.0.win32-py2.7.exe']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5 lxml uff0cu7248u672cu8981u9009u5bf9u5e94u7cfbu7edfuff0cu9519u8befu7684u662fu7528u4e0du4e86u7684u3002u4e0bu8f7du5730u5740uff1axa0',\r\n u' \r\n '],\r\n 'link': [u'https://pypi.python.org/pypi/lxml/3.2.3'],\r\n 'title': [u'https://pypi.python.org/pypi/lxml/3.2.3']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u8981u5b89u88c5scrapyuff0cu8fd0u884cu4ee5u4e0bu547du4ee4uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5', u' \r\n '],\r\n 'link': [u'http://brew.sh/'],\r\n 'title': [u'homebrew']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u8bbeu7f6eu73afu5883u53d8u91cf PATH u6307u5b9axa0homebrewxa0u5305u5728u7cfbu7edfu8f6fu4ef6u5305u524du4f7fu7528uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u53d8u66f4u5b8cu6210u540euff0cu91cdu65b0u52a0u8f7d .bashrc u4f7fu7528u4e0bu9762u7684u547du4ee4uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u63a5u4e0bu6765uff0cu4f7fu7528u4e0bu9762u7684u547du4ee4u5b89u88c5xa0Pythonuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u63a5u4e0bu6765uff0cu5b89u88c5scrapyuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 13:11:06 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 5, 11, 6, 478000),\r\n 'item_scraped_count': 210,\r\n 'log_count/DEBUG': 214,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 5, 11, 5, 197000)}\r\n2016-10-03 13:11:06 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1d:T12b5,"])</script><script>self.__next_f.push([1,"\u003cp\u003e日誌記錄是指使用內置的日誌系統和定義的函數或類來實現應用程序和庫的事件跟蹤。 記錄日誌是一個即用型的程序庫,它可以在Scrapy設置日誌記錄中的設置列表工作。 Scrapy將運行命令時使用 \u003cem\u003escrapy.utils.log.configure_logging()\u003c/em\u003e 設置一些默認設置和如何處理這些設置。\u003c/p\u003e \n\u003ch2\u003e日誌級別 - Log levels\u003c/h2\u003e \n\u003cp\u003e在Python中日誌消息有五種不同級別的嚴重程度。下面的列表以升序顯示標準的日誌消息:\u003c/p\u003e \n\u003cul\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.DEBUG\u003c/code\u003e - 用於調試信息(最低嚴重性)\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.INFO\u003c/code\u003e - 用於信息消息\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.WARNING\u003c/code\u003e - 用於警告消息\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.ERROR\u003c/code\u003e- 用於正則錯誤\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.CRITICAL\u003c/code\u003e - 用於嚴重錯誤(最高嚴重性)\u003c/p\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e如何記錄消息\u003c/h2\u003e \n\u003cp\u003e下面給出簡單的代碼顯示日誌記錄是使用 logging.info 級別的消息。\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogging.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e以上日誌信息可以通過使用 logging.log 參數傳遞,如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogging.log(logging.INFO, \"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e現在,也可以使用 loggers 來關閉消息,通過記錄日誌助手來獲取日誌消息,如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger()\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e可以有多個記錄器,可以通過 logging.getLogger()函數使用名字進行訪問,如下圖所示。\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger('mycustomlogger')\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e自定義記錄器可以通過使用模塊路徑 \u003cstrong\u003ename\u003c/strong\u003e 變量用於其它任何模塊中,如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger(__name__)\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003eSpider的日誌記錄\u003c/h2\u003e \n\u003cp\u003e每個 spider 實例都有一個內置記錄器,並可調用如下:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\nclass LogSpider(scrapy.Spider):\r\n\r\n name = 'logspider'\r\n start_urls = ['http://dmoz.com']\r\n\r\n def parse(self, response):\r\n self.logger.info('Parse function called on %s', response.url)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e在上面的代碼中,logger是使用蜘蛛的名字創建的,但您可以使用Python提供的自定義 logger,如下面的代碼:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nimport scrapy\r\n\r\nlogger = logging.getLogger('customizedlogger')\r\nclass LogSpider(scrapy.Spider):\r\n\r\n name = 'logspider'\r\n start_urls = ['http://dmoz.com']\r\n\r\n def parse(self, response):\r\n logger.info('Parse function called on %s', response.url)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e日誌記錄配置\u003c/h2\u003e \n\u003cp\u003e記錄器不能夠顯示由自己發出消息。因此,它們需要「處理程序」顯示這些消息,以及處理程序將它們被重定向這些消息到各自的目的地,如文件,電子郵件,標準輸出。\u003c/p\u003e \n\u003cp\u003e根據下面的設置,Scrapy 將配置 \u003cem\u003elogger\u003c/em\u003e 的處理程序。\u003c/p\u003e \n\u003ch2\u003e日誌消息設置\u003c/h2\u003e \n\u003cp\u003e下面給出的設置用於配置日誌記錄:\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_FILE\u003c/em\u003e 和 \u003cem\u003eLOG_ENABLED\u003c/em\u003e 決定日誌消息目的地。\u003c/p\u003e \n\u003cp\u003e當您設置了 \u003cem\u003eLOG_ENCODING\u003c/em\u003e ,它不會顯示日誌輸出消息。\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_LEVEL\u003c/em\u003e 設置確定消息的嚴重性順序;嚴重程度不高的消息將被過濾掉。\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_FORMAT\u003c/em\u003e 和 \u003cem\u003eLOG_DATEFORMAT\u003c/em\u003e 用於指定所有消息的佈局。\u003c/p\u003e \n\u003cp\u003e當您設置 LOG_STDOUT 爲 true ,所有的進程的標準輸出和錯誤消息將被重定向到日誌中。\u003c/p\u003e \n\u003ch2\u003e命令行選項\u003c/h2\u003e \n\u003cp\u003eScrapy設置可以通過命令行參數來覆蓋,如下面的表:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e命令\u003c/th\u003e \n \u003cth\u003e描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1\u003c/td\u003e \n \u003ctd\u003e—logfile FILE\u003c/td\u003e \n \u003ctd\u003e覆蓋 LOG_FILE\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2\u003c/td\u003e \n \u003ctd\u003e—loglevel/-L LEVEL\u003c/td\u003e \n \u003ctd\u003e覆蓋 LOG_LEVEL\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3\u003c/td\u003e \n \u003ctd\u003e—nolog\u003c/td\u003e \n \u003ctd\u003e設置 LOG_ENABLED 爲 false\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003cp\u003e要手動配置日誌輸出,可以使用 logging.basicConfig(),如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nfrom scrapy.utils.log import configure_logging\r\n\r\nconfigure_logging(install_root_handler=False)\r\nlogging.basicConfig(\r\n filename='logging.txt',\r\n format='%(levelname)s: %(your_message)s',\r\n level=logging.INFO\r\n)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e參考 - \u003ca href=\"https://doc.scrapy.org/en/0.24/topics/logging.html\"\u003ehttps://doc.scrapy.org/en/0.24/topics/logging.html\u003c/a\u003e\u003c/p\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1e:T121b,"])</script><script>self.__next_f.push([1,"\u003ch2\u003eScrapy快速入門\u003c/h2\u003e \n\u003cp\u003e最好的學習方法是參考例子,Scrapy 也不例外。出於這個原因,有一個 Scrapy 項目名爲 quotesbot 例子,可以參考它瞭解和使用 Scrapy。它包含兩個蜘蛛用於抓取 \u003ca href=\"http://quotes.toscrape.com\"\u003ehttp://quotes.toscrape.com\u003c/a\u003e, 一個使用CSS選擇器,而另一個使用XPath表達式。\u003c/p\u003e \n\u003cblockquote\u003e \n \u003cp\u003e提示:安裝 Scrapy 開發環境配置請參考 - http://www.yiibai.com/scrapy/scrapy_environment.html\u003c/p\u003e \n\u003c/blockquote\u003e \n\u003cp\u003e項目 quotesbot 的源代碼可在: \u003ca href=\"https://github.com/scrapy/quotesbot\" title=\"https://github.com/scrapy/quotesbot\"\u003ehttps://github.com/scrapy/quotesbot\u003c/a\u003e. 在這裏可以找到關於項目 README 更多信息。\u003c/p\u003e \n\u003cp\u003e如果你熟悉使用 Git,可以檢出的代碼。否則點擊\u003ca href=\"https://github.com/scrapy/quotesbot/archive/master.zip\" title=\"這裏下載\"\u003e這裏下載\u003c/a\u003e該項目源代碼的 zip 文件。\u003cbr\u003e現在我們一步步的瞭解和學習這個項目。\u003c/p\u003e \n\u003ch2\u003equotesbot 項目簡介\u003c/h2\u003e \n\u003cp\u003e這是一個 \u003ccode\u003eScrapy\u003c/code\u003e 示例(入門)的項目,它實現從 \u003ca href=\"http://quotes.toscrape.com\" title=\"http://quotes.toscrape.com\"\u003ehttp://quotes.toscrape.com\u003c/a\u003e 上爬行抓取名人名言。\u003c/p\u003e \n\u003cp\u003e這個項目只是針對學習演示目的。\u003c/p\u003e \n\u003ch3\u003e提取數據\u003c/h3\u003e \n\u003cp\u003e這個項目將提取名言,以及各自的作者姓名和標籤相結合。提取的數據看起來是這樣的,如下例子:\u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-json\"\u003e{\r\n 'author': 'Douglas Adams',\r\n 'text': '「I may not have gone where I intended to go, but I think I ...」',\r\n 'tags': ['life', 'navigation']\r\n}\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e蜘蛛 - Spiders\u003c/h2\u003e \n\u003cp\u003e該項目包含兩個蜘蛛(\u003ccode\u003eSpider\u003c/code\u003e),可以使用 \u003ccode\u003elist\u003c/code\u003e 命令列出它們:\u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-shell\"\u003e$ scrapy list\r\ntoscrape-css\r\ntoscrape-xpath\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e這兩種蜘蛛提取同一網站相同的數據,但是如果要刮取 \u003ccode\u003eCSS\u003c/code\u003e,則使用 \u003ccode\u003eCSS\u003c/code\u003e 選擇器,而要刮取 \u003ccode\u003eXPath\u003c/code\u003e 則採用 \u003ccode\u003eXPath\u003c/code\u003e 表達式。\u003c/p\u003e \n\u003cp\u003e您可以通過Scrapy教程去了解更多的蜘蛛。\u003c/p\u003e \n\u003ch2\u003e運行蜘蛛\u003c/h2\u003e \n\u003cp\u003e您可以使用 \u003ccode\u003escrapy\u003c/code\u003e 爬行的命令,如運行一個蜘蛛:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e$ scrapy crawl toscrape-css\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e如果想保存數據刮到一個文件,可以通過 \u003ccode\u003e-o\u003c/code\u003e 選項:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e$ scrapy crawl toscrape-css -o quotes.json\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e代碼實現\u003c/h2\u003e \n\u003cp\u003e我們先來看看 \u003ccode\u003equotesbot/spiders/toscrape-xpath.py\u003c/code\u003e 的代碼實現 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-python\"\u003e# -*- coding: utf-8 -*-\r\nimport scrapy\r\n\r\n\r\nclass ToScrapeSpiderXPath(scrapy.Spider):\r\n name = 'toscrape-xpath'\r\n start_urls = [\r\n 'http://quotes.toscrape.com/',\r\n ]\r\n\r\n def parse(self, response):\r\n for quote in response.xpath('//div[@class=\"quote\"]'):\r\n yield {\r\n 'text': quote.xpath('./span[@class=\"text\"]/text()').extract_first(),\r\n 'author': quote.xpath('.//small[@class=\"author\"]/text()').extract_first(),\r\n 'tags': quote.xpath('.//div[@class=\"tags\"]/a[@class=\"tag\"]/text()').extract()\r\n }\r\n\r\n next_page_url = response.xpath('//li[@class=\"next\"]/a/@href').extract_first()\r\n if next_page_url is not None:\r\n yield scrapy.Request(response.urljoin(next_page_url))\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e另外一個 Spider 採用 XPath 表達式 \u003ccode\u003equotesbot/spiders/toscrape-xpath.py\u003c/code\u003e 的代碼實現 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-python\"\u003e# -*- coding: utf-8 -*-\r\nimport scrapy\r\n\r\n\r\nclass ToScrapeSpiderXPath(scrapy.Spider):\r\n name = 'toscrape-xpath'\r\n start_urls = [\r\n 'http://quotes.toscrape.com/',\r\n ]\r\n\r\n def parse(self, response):\r\n for quote in response.xpath('//div[@class=\"quote\"]'):\r\n yield {\r\n 'text': quote.xpath('./span[@class=\"text\"]/text()').extract_first(),\r\n 'author': quote.xpath('.//small[@class=\"author\"]/text()').extract_first(),\r\n 'tags': quote.xpath('.//div[@class=\"tags\"]/a[@class=\"tag\"]/text()').extract()\r\n }\r\n\r\n next_page_url = response.xpath('//li[@class=\"next\"]/a/@href').extract_first()\r\n if next_page_url is not None:\r\n yield scrapy.Request(response.urljoin(next_page_url))\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e參考\u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e\u003ca href=\"https://doc.scrapy.org/en/1.2/intro/examples.html\" title=\"https://doc.scrapy.org/en/1.2/intro/examples.html\"\u003ehttps://doc.scrapy.org/en/1.2/intro/examples.html\u003c/a\u003e\u003c/li\u003e \n\u003c/ul\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"1f:T1bb4,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e \n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u0026lt;head\u0026gt; 元素中的 \u0026lt;title\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e/html/head/title/text(): 這將選擇 \u0026lt;title\u0026gt; 元素中的文本。\u003c/p\u003e \n\u003cp\u003e//td: 這將選擇所有的 \u0026lt;td\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e//div[\u003ca href=\"https://github.com/class\" title=\"@class\" class=\"at-link\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e \n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e方法 \u0026amp; 描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003eextract()\u003c/td\u003e \n \u003ctd\u003e它返回一個unicode字符串以及所選數據\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ere()\u003c/td\u003e \n \u003ctd\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003expath()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ecss()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch2\u003e在Shell中使用選擇器\u003c/h2\u003e \n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\r\n[s] item {}\r\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\r\n[s] spider \u0026lt;firstSpider 'first' at 0x47f9f28\u0026gt;\r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e \n\u003cp\u003e例如:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath('//title')\r\n[\u0026lt;Selector xpath='//title' data=u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title').extract()\r\n[u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()')\r\n[\u0026lt;Selector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').re('(w+):')\r\n[]\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e提取數據\u003c/h2\u003e \n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e \n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e \n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li')\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇描述:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/@href').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\n\r\nclass MyprojectSpider(scrapy.Spider):\r\n name = \"project\"\r\n allowed_domains = [\"dmoz.org\"]\r\n start_urls = [\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\r\n ]\r\n\r\n def parse(self, response):\r\n for sel in response.xpath('//ul/li'):\r\n title = sel.xpath('a/text()').extract()\r\n link = sel.xpath('a/@href').extract()\r\n desc = sel.xpath('text()').extract()\r\n print title, link, desc\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"20:T185f,"])</script><script>self.__next_f.push([1,"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\n\n/html/head/title: \n這將選擇 HTML 文檔中的 \u003chead\u003e 元素中的 \u003ctitle\u003e 元素。\n\n/html/head/title/text(): 這將選擇 \u003ctitle\u003e 元素中的文本。\n\n//td: 這將選擇所有的 \u003ctd\u003e 元素。\n\n//div\\[[@class](https://github.com/class \"@class\")\\=」slice」\\]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\n\n選擇器有四個基本的方法,如下所示:\n\nS.N.\n\n方法 \u0026 描述\n\nextract()\n\n它返回一個unicode字符串以及所選數據\n\nre()\n\n它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\n\nxpath()\n\n它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\n\ncss()\n\n它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\n\n在Shell中使用選擇器\n------------\n\n若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 [IPython](http://ipython.org/)。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\n\n```\nscrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\n```\n\nshell 執行後結果如下圖所示:\n\n```\nD:first_scrapy\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\n['scrapy.extensions.telnet.TelnetConsole',\n 'scrapy.extensions.corestats.CoreStats']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\n[]\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u003cGET http://www.yiibai.com/robots.txt\u003e (referer: None)\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u003cGET http://www.yiibai.com/scrapy/scrapy_environment.html\u003e (referer: None)\n[s] Available Scrapy objects:\n[s] crawler \u003cscrapy.crawler.Crawler object at 0x00000000042E3E80\u003e\n[s] item {}\n[s] request \u003cGET http://www.yiibai.com/scrapy/scrapy_environment.html\u003e\n[s] response \u003c200 http://www.yiibai.com/scrapy/scrapy_environment.html\u003e\n[s] settings \u003cscrapy.settings.Settings object at 0x00000000042E3E10\u003e\n[s] spider \u003cfirstSpider 'first' at 0x47f9f28\u003e\n[s] Useful shortcuts:\n[s] shelp() Shell help (print this help)\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\n[s] view(response) View response in a browser\n\u003e\u003e\u003e\n```\n\n當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\n\n例如:\n\n```\n\u003e\u003e\u003e response.xpath('//title')\n[\u003cSelector xpath='//title' data=u'\u003ctitle\u003eScrapyu5b89u88c5 - Scrapyu6559u7a0b\u003c/title\u003e'\u003e]\n\u003e\u003e\u003e response.xpath('//title').extract()\n[u'\u003ctitle\u003eScrapyu5b89u88c5 - Scrapyu6559u7a0b\u003c/title\u003e']\n\u003e\u003e\u003e response.xpath('//title/text()')\n[\u003cSelector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u003e]\n\u003e\u003e\u003e response.xpath('//title/text()').extract()\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\n\u003e\u003e\u003e response.xpath('//title/text()').extract()\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\n\u003e\u003e\u003e response.xpath('//title/text()').re('(w+):')\n[]\n\u003e\u003e\u003e\n```\n\n提取數據\n----\n\n從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\n\n代碼的下面行顯示了不同類型的數據的提取:\n\n選擇 li 標籤內的數據:\n\n```\nresponse.xpath('//ul/li')\n```\n\n對於選擇描述:\n\n```\nresponse.xpath('//ul/li/text()').extract()\n```\n\n對於選擇網站標題:\n\n```\nresponse.xpath('//ul/li/a/text()').extract()\n```\n\n對於選擇網站的鏈接:\n\n```\nresponse.xpath('//ul/li/a/@href').extract()\n```\n\n下面的代碼用於演示上述提取的用法:\n\n```\nimport scrapy\n\nclass MyprojectSpider(scrapy.Spider):\n name = \"project\"\n allowed_domains = [\"dmoz.org\"]\n start_urls = [\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\n ]\n\n def parse(self, response):\n for sel in response.xpath('//ul/li'):\n title = sel.xpath('a/text()').extract()\n link = sel.xpath('a/@href').extract()\n desc = sel.xpath('text()').extract()\n print title, link, desc\n```"])</script><script>self.__next_f.push([1,"21:T1d00,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e\n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u003chead\u003e 元素中的 \u003ctitle\u003e 元素。\u003c/p\u003e\n\u003cp\u003e/html/head/title/text(): 這將選擇 \u003ctitle\u003e 元素中的文本。\u003c/p\u003e\n\u003cp\u003e//td: 這將選擇所有的 \u003ctd\u003e 元素。\u003c/p\u003e\n\u003cp\u003e//div[\u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://github.com/class\" title=\"@class\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e\n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e\n\u003cp\u003eS.N.\u003c/p\u003e\n\u003cp\u003e方法 \u0026amp; 描述\u003c/p\u003e\n\u003cp\u003eextract()\u003c/p\u003e\n\u003cp\u003e它返回一個unicode字符串以及所選數據\u003c/p\u003e\n\u003cp\u003ere()\u003c/p\u003e\n\u003cp\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/p\u003e\n\u003cp\u003expath()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/p\u003e\n\u003cp\u003ecss()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/p\u003e\n\u003ch2 id=\"在shell中使用選擇器\"\u003e在Shell中使用選擇器\u003c/h2\u003e\n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003escrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {\u0026#39;NEWSPIDER_MODULE\u0026#39;: \u0026#39;first_scrapy.spiders\u0026#39;, \u0026#39;ROBOTSTXT_OBEY\u0026#39;: True, \u0026#39;DUPEFILTER_CLASS\u0026#39;: \u0026#39;scrapy.dupefilters.BaseDupeFilter\u0026#39;, \u0026#39;SPIDER_MODULES\u0026#39;: [\u0026#39;first_scrapy.spiders\u0026#39;], \u0026#39;BOT_NAME\u0026#39;: \u0026#39;first_scrapy\u0026#39;, \u0026#39;LOGSTATS_INTERVAL\u0026#39;: 0}\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\n[\u0026#39;scrapy.extensions.telnet.TelnetConsole\u0026#39;,\n \u0026#39;scrapy.extensions.corestats.CoreStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\n[\u0026#39;scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.useragent.UserAgentMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.retry.RetryMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.RedirectMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.cookies.CookiesMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.stats.DownloaderStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\n[\u0026#39;scrapy.spidermiddlewares.httperror.HttpErrorMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.offsite.OffsiteMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.referer.RefererMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.urllength.UrlLengthMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.depth.DepthMiddleware\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\n[]\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\n[s] Available Scrapy objects:\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\n[s] item {}\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\n[s] spider \u0026lt;firstSpider \u0026#39;first\u0026#39; at 0x47f9f28\u0026gt;\n[s] Useful shortcuts:\n[s] shelp() Shell help (print this help)\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\n[s] view(response) View response in a browser\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e\n\u003cp\u003e例如:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title\u0026#39; data=u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;).extract()\n[u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title/text()\u0026#39; data=u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).re(\u0026#39;(w+):\u0026#39;)\n[]\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"提取數據\"\u003e提取數據\u003c/h2\u003e\n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e\n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e\n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li\u0026#39;)\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇描述:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/@href\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eimport scrapy\n\nclass MyprojectSpider(scrapy.Spider):\n name = \u0026quot;project\u0026quot;\n allowed_domains = [\u0026quot;dmoz.org\u0026quot;]\n start_urls = [\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\u0026quot;,\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\u0026quot;\n ]\n\n def parse(self, response):\n for sel in response.xpath(\u0026#39;//ul/li\u0026#39;):\n title = sel.xpath(\u0026#39;a/text()\u0026#39;).extract()\n link = sel.xpath(\u0026#39;a/@href\u0026#39;).extract()\n desc = sel.xpath(\u0026#39;text()\u0026#39;).extract()\n print title, link, desc\u003c/code\u003e\u003c/pre\u003e\n"])</script><script>self.__next_f.push([1,"24:T1d00,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e\n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u003chead\u003e 元素中的 \u003ctitle\u003e 元素。\u003c/p\u003e\n\u003cp\u003e/html/head/title/text(): 這將選擇 \u003ctitle\u003e 元素中的文本。\u003c/p\u003e\n\u003cp\u003e//td: 這將選擇所有的 \u003ctd\u003e 元素。\u003c/p\u003e\n\u003cp\u003e//div[\u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://github.com/class\" title=\"@class\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e\n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e\n\u003cp\u003eS.N.\u003c/p\u003e\n\u003cp\u003e方法 \u0026amp; 描述\u003c/p\u003e\n\u003cp\u003eextract()\u003c/p\u003e\n\u003cp\u003e它返回一個unicode字符串以及所選數據\u003c/p\u003e\n\u003cp\u003ere()\u003c/p\u003e\n\u003cp\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/p\u003e\n\u003cp\u003expath()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/p\u003e\n\u003cp\u003ecss()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/p\u003e\n\u003ch2 id=\"在shell中使用選擇器\"\u003e在Shell中使用選擇器\u003c/h2\u003e\n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003escrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {\u0026#39;NEWSPIDER_MODULE\u0026#39;: \u0026#39;first_scrapy.spiders\u0026#39;, \u0026#39;ROBOTSTXT_OBEY\u0026#39;: True, \u0026#39;DUPEFILTER_CLASS\u0026#39;: \u0026#39;scrapy.dupefilters.BaseDupeFilter\u0026#39;, \u0026#39;SPIDER_MODULES\u0026#39;: [\u0026#39;first_scrapy.spiders\u0026#39;], \u0026#39;BOT_NAME\u0026#39;: \u0026#39;first_scrapy\u0026#39;, \u0026#39;LOGSTATS_INTERVAL\u0026#39;: 0}\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\n[\u0026#39;scrapy.extensions.telnet.TelnetConsole\u0026#39;,\n \u0026#39;scrapy.extensions.corestats.CoreStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\n[\u0026#39;scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.useragent.UserAgentMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.retry.RetryMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.RedirectMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.cookies.CookiesMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.stats.DownloaderStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\n[\u0026#39;scrapy.spidermiddlewares.httperror.HttpErrorMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.offsite.OffsiteMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.referer.RefererMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.urllength.UrlLengthMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.depth.DepthMiddleware\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\n[]\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\n[s] Available Scrapy objects:\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\n[s] item {}\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\n[s] spider \u0026lt;firstSpider \u0026#39;first\u0026#39; at 0x47f9f28\u0026gt;\n[s] Useful shortcuts:\n[s] shelp() Shell help (print this help)\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\n[s] view(response) View response in a browser\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e\n\u003cp\u003e例如:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title\u0026#39; data=u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;).extract()\n[u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title/text()\u0026#39; data=u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).re(\u0026#39;(w+):\u0026#39;)\n[]\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"提取數據\"\u003e提取數據\u003c/h2\u003e\n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e\n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e\n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li\u0026#39;)\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇描述:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/@href\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eimport scrapy\n\nclass MyprojectSpider(scrapy.Spider):\n name = \u0026quot;project\u0026quot;\n allowed_domains = [\u0026quot;dmoz.org\u0026quot;]\n start_urls = [\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\u0026quot;,\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\u0026quot;\n ]\n\n def parse(self, response):\n for sel in response.xpath(\u0026#39;//ul/li\u0026#39;):\n title = sel.xpath(\u0026#39;a/text()\u0026#39;).extract()\n link = sel.xpath(\u0026#39;a/@href\u0026#39;).extract()\n desc = sel.xpath(\u0026#39;text()\u0026#39;).extract()\n print title, link, desc\u003c/code\u003e\u003c/pre\u003e\n"])</script><script>self.__next_f.push([1,"26:T1bb4,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e \n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u0026lt;head\u0026gt; 元素中的 \u0026lt;title\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e/html/head/title/text(): 這將選擇 \u0026lt;title\u0026gt; 元素中的文本。\u003c/p\u003e \n\u003cp\u003e//td: 這將選擇所有的 \u0026lt;td\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e//div[\u003ca href=\"https://github.com/class\" title=\"@class\" class=\"at-link\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e \n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e方法 \u0026amp; 描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003eextract()\u003c/td\u003e \n \u003ctd\u003e它返回一個unicode字符串以及所選數據\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ere()\u003c/td\u003e \n \u003ctd\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003expath()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ecss()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch2\u003e在Shell中使用選擇器\u003c/h2\u003e \n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\r\n[s] item {}\r\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\r\n[s] spider \u0026lt;firstSpider 'first' at 0x47f9f28\u0026gt;\r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e \n\u003cp\u003e例如:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath('//title')\r\n[\u0026lt;Selector xpath='//title' data=u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title').extract()\r\n[u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()')\r\n[\u0026lt;Selector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').re('(w+):')\r\n[]\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e提取數據\u003c/h2\u003e \n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e \n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e \n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li')\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇描述:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/@href').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\n\r\nclass MyprojectSpider(scrapy.Spider):\r\n name = \"project\"\r\n allowed_domains = [\"dmoz.org\"]\r\n start_urls = [\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\r\n ]\r\n\r\n def parse(self, response):\r\n for sel in response.xpath('//ul/li'):\r\n title = sel.xpath('a/text()').extract()\r\n link = sel.xpath('a/@href').extract()\r\n desc = sel.xpath('text()').extract()\r\n print title, link, desc\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"27:T185f,"])</script><script>self.__next_f.push([1,"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\n\n/html/head/title: \n這將選擇 HTML 文檔中的 \u003chead\u003e 元素中的 \u003ctitle\u003e 元素。\n\n/html/head/title/text(): 這將選擇 \u003ctitle\u003e 元素中的文本。\n\n//td: 這將選擇所有的 \u003ctd\u003e 元素。\n\n//div\\[[@class](https://github.com/class \"@class\")\\=」slice」\\]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\n\n選擇器有四個基本的方法,如下所示:\n\nS.N.\n\n方法 \u0026 描述\n\nextract()\n\n它返回一個unicode字符串以及所選數據\n\nre()\n\n它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\n\nxpath()\n\n它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\n\ncss()\n\n它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\n\n在Shell中使用選擇器\n------------\n\n若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 [IPython](http://ipython.org/)。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\n\n```\nscrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\n```\n\nshell 執行後結果如下圖所示:\n\n```\nD:first_scrapy\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\n['scrapy.extensions.telnet.TelnetConsole',\n 'scrapy.extensions.corestats.CoreStats']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\n[]\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u003cGET http://www.yiibai.com/robots.txt\u003e (referer: None)\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u003cGET http://www.yiibai.com/scrapy/scrapy_environment.html\u003e (referer: None)\n[s] Available Scrapy objects:\n[s] crawler \u003cscrapy.crawler.Crawler object at 0x00000000042E3E80\u003e\n[s] item {}\n[s] request \u003cGET http://www.yiibai.com/scrapy/scrapy_environment.html\u003e\n[s] response \u003c200 http://www.yiibai.com/scrapy/scrapy_environment.html\u003e\n[s] settings \u003cscrapy.settings.Settings object at 0x00000000042E3E10\u003e\n[s] spider \u003cfirstSpider 'first' at 0x47f9f28\u003e\n[s] Useful shortcuts:\n[s] shelp() Shell help (print this help)\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\n[s] view(response) View response in a browser\n\u003e\u003e\u003e\n```\n\n當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\n\n例如:\n\n```\n\u003e\u003e\u003e response.xpath('//title')\n[\u003cSelector xpath='//title' data=u'\u003ctitle\u003eScrapyu5b89u88c5 - Scrapyu6559u7a0b\u003c/title\u003e'\u003e]\n\u003e\u003e\u003e response.xpath('//title').extract()\n[u'\u003ctitle\u003eScrapyu5b89u88c5 - Scrapyu6559u7a0b\u003c/title\u003e']\n\u003e\u003e\u003e response.xpath('//title/text()')\n[\u003cSelector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u003e]\n\u003e\u003e\u003e response.xpath('//title/text()').extract()\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\n\u003e\u003e\u003e response.xpath('//title/text()').extract()\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\n\u003e\u003e\u003e response.xpath('//title/text()').re('(w+):')\n[]\n\u003e\u003e\u003e\n```\n\n提取數據\n----\n\n從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\n\n代碼的下面行顯示了不同類型的數據的提取:\n\n選擇 li 標籤內的數據:\n\n```\nresponse.xpath('//ul/li')\n```\n\n對於選擇描述:\n\n```\nresponse.xpath('//ul/li/text()').extract()\n```\n\n對於選擇網站標題:\n\n```\nresponse.xpath('//ul/li/a/text()').extract()\n```\n\n對於選擇網站的鏈接:\n\n```\nresponse.xpath('//ul/li/a/@href').extract()\n```\n\n下面的代碼用於演示上述提取的用法:\n\n```\nimport scrapy\n\nclass MyprojectSpider(scrapy.Spider):\n name = \"project\"\n allowed_domains = [\"dmoz.org\"]\n start_urls = [\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\n ]\n\n def parse(self, response):\n for sel in response.xpath('//ul/li'):\n title = sel.xpath('a/text()').extract()\n link = sel.xpath('a/@href').extract()\n desc = sel.xpath('text()').extract()\n print title, link, desc\n```"])</script><script>self.__next_f.push([1,"28:T1d00,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e\n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u003chead\u003e 元素中的 \u003ctitle\u003e 元素。\u003c/p\u003e\n\u003cp\u003e/html/head/title/text(): 這將選擇 \u003ctitle\u003e 元素中的文本。\u003c/p\u003e\n\u003cp\u003e//td: 這將選擇所有的 \u003ctd\u003e 元素。\u003c/p\u003e\n\u003cp\u003e//div[\u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"https://github.com/class\" title=\"@class\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e\n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e\n\u003cp\u003eS.N.\u003c/p\u003e\n\u003cp\u003e方法 \u0026amp; 描述\u003c/p\u003e\n\u003cp\u003eextract()\u003c/p\u003e\n\u003cp\u003e它返回一個unicode字符串以及所選數據\u003c/p\u003e\n\u003cp\u003ere()\u003c/p\u003e\n\u003cp\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/p\u003e\n\u003cp\u003expath()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/p\u003e\n\u003cp\u003ecss()\u003c/p\u003e\n\u003cp\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/p\u003e\n\u003ch2 id=\"在shell中使用選擇器\"\u003e在Shell中使用選擇器\u003c/h2\u003e\n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca target=\"_blank\" rel=\"nofollow noreferrer\" href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003escrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \u0026quot;http://www.yiibai.com/scrapy/scrapy_environment.html\u0026quot;\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {\u0026#39;NEWSPIDER_MODULE\u0026#39;: \u0026#39;first_scrapy.spiders\u0026#39;, \u0026#39;ROBOTSTXT_OBEY\u0026#39;: True, \u0026#39;DUPEFILTER_CLASS\u0026#39;: \u0026#39;scrapy.dupefilters.BaseDupeFilter\u0026#39;, \u0026#39;SPIDER_MODULES\u0026#39;: [\u0026#39;first_scrapy.spiders\u0026#39;], \u0026#39;BOT_NAME\u0026#39;: \u0026#39;first_scrapy\u0026#39;, \u0026#39;LOGSTATS_INTERVAL\u0026#39;: 0}\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\n[\u0026#39;scrapy.extensions.telnet.TelnetConsole\u0026#39;,\n \u0026#39;scrapy.extensions.corestats.CoreStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\n[\u0026#39;scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.useragent.UserAgentMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.retry.RetryMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.redirect.RedirectMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.cookies.CookiesMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware\u0026#39;,\n \u0026#39;scrapy.downloadermiddlewares.stats.DownloaderStats\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\n[\u0026#39;scrapy.spidermiddlewares.httperror.HttpErrorMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.offsite.OffsiteMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.referer.RefererMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.urllength.UrlLengthMiddleware\u0026#39;,\n \u0026#39;scrapy.spidermiddlewares.depth.DepthMiddleware\u0026#39;]\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\n[]\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\n[s] Available Scrapy objects:\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\n[s] item {}\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\n[s] spider \u0026lt;firstSpider \u0026#39;first\u0026#39; at 0x47f9f28\u0026gt;\n[s] Useful shortcuts:\n[s] shelp() Shell help (print this help)\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\n[s] view(response) View response in a browser\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e\n\u003cp\u003e例如:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title\u0026#39; data=u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title\u0026#39;).extract()\n[u\u0026#39;\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;)\n[\u0026lt;Selector xpath=\u0026#39;//title/text()\u0026#39; data=u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;\u0026gt;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).extract()\n[u\u0026#39;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026#39;]\n\u0026gt;\u0026gt;\u0026gt; response.xpath(\u0026#39;//title/text()\u0026#39;).re(\u0026#39;(w+):\u0026#39;)\n[]\n\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"提取數據\"\u003e提取數據\u003c/h2\u003e\n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e\n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e\n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li\u0026#39;)\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇描述:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/text()\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse.xpath(\u0026#39;//ul/li/a/@href\u0026#39;).extract()\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eimport scrapy\n\nclass MyprojectSpider(scrapy.Spider):\n name = \u0026quot;project\u0026quot;\n allowed_domains = [\u0026quot;dmoz.org\u0026quot;]\n start_urls = [\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\u0026quot;,\n \u0026quot;http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\u0026quot;\n ]\n\n def parse(self, response):\n for sel in response.xpath(\u0026#39;//ul/li\u0026#39;):\n title = sel.xpath(\u0026#39;a/text()\u0026#39;).extract()\n link = sel.xpath(\u0026#39;a/@href\u0026#39;).extract()\n desc = sel.xpath(\u0026#39;text()\u0026#39;).extract()\n print title, link, desc\u003c/code\u003e\u003c/pre\u003e\n"])</script><script>self.__next_f.push([1,"29:T912,"])</script><script>self.__next_f.push([1,"\u003ch2\u003e Scrapy是什麼? \u003c/h2\u003e \n\u003cdiv\u003e\n Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。 \n \u003cbr\u003e \n \u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-1.png\" alt=\"Scrapy教程\"\u003e \n \u003cbr\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n\u003c/div\u003e \n\u003ch2\u003e 歷史 \u003c/h2\u003e \n\u003cdiv\u003e\n Scrapy最初是在 2008年6月26日在BSD許可協議下發布,並在2015年6月發佈的一個里程碑版本1.0。 \n\u003c/div\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 爲什麼要使用Scrapy? \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它更容易構建和大規模的抓取項目; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它內置的機制被稱爲選擇器,用於從網站(網頁)上提取數據; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它異步處理請求,速度十分快; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 它可以使用 \n \u003ca href=\"http://doc.scrapy.org/en/latest/topics/autothrottle.html\"\u003e自動調節機制\u003c/a\u003e自動調整爬行速度; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 確保開發人員可訪問性; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n Scrapy的特點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy是一個開源和免費使用的網絡爬蟲框架; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy生成格式導出如:JSON,CSV和XML; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy內置支持從源代碼,使用XPath或CSS表達式的選擇器來提取數據; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy基於爬蟲,允許以自動方式從網頁中提取數據; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 優點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy很容易擴展,快速和功能強大; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 這是一個跨平臺應用程序框架(在Windows,Linux,Mac\u0026nbsp;OS和BSD)。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy請求調度和異步處理; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy附帶了一個名爲Scrapyd的內置服務,它允許使用JSON\u0026nbsp;Web服務上傳項目和控制蜘蛛。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 也能夠刮削任何網站,即使該網站不具有原始數據訪問API; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 缺點 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n Scrapy只面向Python2.7+以上版本; \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 不同的操作系統安裝不太相同; \n \u003c/div\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2a:T154d,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n 在本章中,我們將瞭解如何安裝和設置Scrapy。Scrapy必須與Python一起安裝。 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy可以通過使用 pip 進行安裝。運行以下命令: \n \u003c/div\u003e \n \u003cpre\u003epip install Scrapy\u003c/pre\u003e \n \u003ch2\u003e Windows系統上安裝(本教程) \u003c/h2\u003e \n \u003cdiv\u003e \n \u003cdiv\u003e\n 在Window系統上安裝Scrapy,是一個比較複雜的事項,在寫本教程的時候,看到網上有人說用了3天時間才裝好,嚇我一跳,不過還好,我也算是比較喜歡折騰的那麼一個人。需要一點點耐心就好。 下載文件地址 -\u0026nbsp; \n \u003ca href=\"http://pan.baidu.com/s/1nv6ObKt\"\u003ehttp://pan.baidu.com/s/1nv6ObKt\u003c/a\u003e \n \u003c/div\u003e 注:Windows操作系統是不支持Python3 的 Scrapy。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e 從\u0026nbsp;\u003ca href=\"https://www.python.org/downloads/\"\u003ePython\u003c/a\u003e\u0026nbsp;安裝 Python2.7 \u003c/p\u003e \n \u003cdiv\u003e\n 添加下面的路徑到PATH設置環境變量: \n \u003c/div\u003e \u003cpre\u003eC:\\Python27\\;C:\\Python27\\Scripts\\;\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以通過使用以下命令來檢查Python版本: \n \u003c/div\u003e \u003cpre\u003epython --version\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 安裝\u0026nbsp;\u003ca href=\"http://slproweb.com/products/Win32OpenSSL.html\"\u003eOpenSSL\u003c/a\u003e\u0026nbsp;或下載地址 :\u003ca href=\"http://www.egenix.com/cryptodownload/?file=egenix-pyopenssl-0.13.0_1.0.0g_1.win-amd64-py2.7.msi\"\u003ehttp://www.egenix.com/cryptodownload/?file=egenix-pyopenssl-0.13.0_1.0.0g_1.win-amd64-py2.7.msi\u003c/a\u003e(重點)\u003cbr\u003e 添加 C:\\OpenSSL-Win64\\bin\u0026nbsp;在您的系統環境變量中; \u003c/p\u003e \n \u003cdiv\u003e\n 注:OpenSSL預裝在所有的操作系統(除了Windows)。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 安裝\u0026nbsp;\u003ca href=\"http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF\"\u003eVisual C++ 2008\u003c/a\u003e\u0026nbsp;再發行組件或\u003ca href=\"http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF\"\u003eVisual C++ 2008 Redistributables\u003c/a\u003e\u0026nbsp;和\u0026nbsp;\u003ca href=\"http://slproweb.com/download/Win64OpenSSL-1_0_1f.exe\"\u003eWin64 OpenSSL v1.0.1f\u003c/a\u003e \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cul\u003e \n \u003cli\u003e 安裝\u0026nbsp;\u003ca href=\"http://sourceforge.net/projects/pywin32/\"\u003epywin32\u003c/a\u003e\u0026amp;amd64 \u003c/li\u003e \n \u003cli\u003e 安裝 Python2.7.9 以下的\u0026nbsp;\u003ca href=\"https://pip.pypa.io/en/latest/installing/\"\u003epip\u003c/a\u003e\u0026nbsp;或者下載地址:\u0026nbsp;\u003ca href=\"https://pypi.python.org/pypi/setuptools#files\"\u003ehttps://pypi.python.org/pypi/setuptools#files\u003c/a\u003e\u003ca href=\"https://pypi.python.org/pypi/setuptools#files\"\u003e\u0026nbsp;\u003c/a\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cul\u003e \n \u003cli\u003e 您可以通過使用以下命令來檢查 pip 版本: \u003cpre\u003epip --version\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 安裝twisted,下載地址 -\u003ca href=\"https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0\"\u003ehttps://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0\u003c/a\u003e \u003c/li\u003e \n \u003cli\u003e 安裝\u0026nbsp;zope 接口:\u003ca href=\"https://pypi.python.org/pypi/zope.interface/4.1.0\"\u003ehttps://pypi.python.org/pypi/zope.interface/4.1.0\u003c/a\u003e\u0026nbsp;選擇倒數第二個\u0026nbsp;\u003ca href=\"https://pypi.python.org/packages/2.7/z/zope.interface/zope.interface-4.1.0.win32-py2.7.exe#md5=c0100a3cd6de6ecc3cd3b4d678ec7931\"\u003ezope.interface-4.1.0.win32-py2.7.exe\u003c/a\u003e\u0026nbsp;\u003cbr\u003e \u003c/li\u003e \n \u003cli\u003e 安裝 lxml ,版本要選對應系統,錯誤的是用不了的。下載地址:\u0026nbsp;\u003ca href=\"https://pypi.python.org/pypi/lxml/3.2.3\"\u003ehttps://pypi.python.org/pypi/lxml/3.2.3\u003c/a\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cul\u003e \n \u003cli\u003e 要安裝scrapy,運行以下命令: \u003cpre\u003epip install Scrapy\u003c/pre\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cdiv\u003e\n 成功後,界面長這樣 -\u0026nbsp; \n \u003cbr\u003e \n \u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-2.png\" alt=\"Scrapy安裝\"\u003e \n \u003cbr\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e Ubuntu系統 \u003c/h2\u003e \n \u003cp\u003e Python的最新版本是預先安裝在Ubuntu操作系統。使用由 Scrapinghub 提供\u0026nbsp;Ubuntu 的軟件包 apt-get。要使用這些軟件包: \u003c/p\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 需要輸入用於登錄\u0026nbsp;Scrapy\u0026nbsp;包 APT 的 GPG密鑰: \n \u003c/div\u003e \u003cpre\u003esudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 627220E7\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 接下來,使用下面的命令來創建 /etc/apt/sources.list.d/scrapy.list 文件: \n \u003c/div\u003e \u003cpre\u003eecho 'deb http://archive.scrapy.org/ubuntu scrapy main'| sudo tee /etc/apt/sources.list.d/scrapy.list\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 更新軟件包列表並安裝scrapy: \n \u003c/div\u003e \u003cpre\u003esudo apt-get update \u0026amp;\u0026amp; sudo apt-get install scrapy\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e Archlinux系統 \u003c/h2\u003e \n \u003cdiv\u003e\n 可以使用下面的命令從AUR\u0026nbsp;Scrapy 包安裝 Scrapy: \n \u003c/div\u003e \n \u003cpre\u003eyaourt -S scrapy\u003c/pre\u003e \n \u003ch2\u003e Mac OS X系統 \u003c/h2\u003e \n \u003cdiv\u003e\n 使用下面的命令來安裝 Xcode 命令行工具: \n \u003c/div\u003e \n \u003cpre\u003excode-select--install\u003c/pre\u003e \n \u003cdiv\u003e\n 而不是使用系統的Python,安裝新的更新版本,不與系統的其餘部分衝突。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e 安裝\u003ca href=\"http://brew.sh/\"\u003ehomebrew\u003c/a\u003e \u003c/li\u003e \n \u003cli\u003e 設置環境變量 PATH 指定\u0026nbsp;homebrew\u0026nbsp;包在系統軟件包前使用: \u003cpre\u003eecho \"export PATH=/usr/local/bin:/usr/local/sbin:$PATH\"\u0026gt;\u0026gt;~/.bashrc\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 變更完成後,重新加載 .bashrc 使用下面的命令: \u003cpre\u003esource ~/.bashrc\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 接下來,使用下面的命令安裝\u0026nbsp;Python: \u003cpre\u003ebrew install python\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e 接下來,安裝scrapy: \u003cpre\u003epip install Scrapy\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2b:T13b9,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n Scrapy命令行工具用於控制Scrapy,它通常被稱爲「Scrapy工具」。它包括用於不同對象的參數和選項組的命令。 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 配置設置 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n scrapy\u0026nbsp;會找到\u0026nbsp;scrapy.cfg\u0026nbsp;文件中設置的配置。如下面提到的: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e C:\\scrapy(project folder)\\scrapy.cfg\u0026nbsp;在系統中; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e ~/.config/scrapy.cfg ($XDG_CONFIG_HOME)\u0026nbsp;and\u0026nbsp;~/.scrapy.cfg ($HOME)\u0026nbsp;,這些是全局設置 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以在項目的根目錄裏面找到 scrapy.cfg 這個文件。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n Scrapy還可以使用以下的環境變量來配置: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_SETTINGS_MODULE \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_PROJECT \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e SCRAPY_PYTHON_SHELL \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 默認Scrapy項目結構 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 下面的結構顯示 Scrapy項目的默認文件結構: \n \u003c/div\u003e \n \u003cpre\u003escrapy.cfg - Deploy the configuration file\r\nproject_name/ - Name of the project\r\n _init_.py\r\n items.py - It is project's items file\r\n pipelines.py - It is project's pipelines file\r\n settings.py - It is project's settings file\r\n spiders - It is the spiders directory\r\n _init_.py\r\n spider_name.py\r\n . . .\r\u003c/pre\u003e \n \u003cdiv\u003e\n scrapy.cfg 文件是在項目的根目錄,其中包括項目名稱與項目設置。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cpre\u003e[settings]\r\ndefault = [name of the project].settings\r\n\r\n[deploy]\r\n#url = http://localhost:6800/\r\nproject = [name of the project]\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用Scrapy工具 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 通過使用Scrapy工具,它會提供一些可使用以的命令如下所示: \n \u003c/div\u003e \n \u003cpre\u003eScrapy X.Y - no active project\r\nUsage:\r\n scrapy [options] [arguments]\r\nAvailable commands:\r\n crawl It puts spider (handle the URL) to work for crawling data\r\n fetch It fetches the response from the given URL\r\u003c/pre\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 創建項目 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n 您可以使用下面的命令來創建 Scrapy 項目: \n \u003c/div\u003e \n \u003cpre\u003escrapy startproject scrapy_project\r\u003c/pre\u003e \n \u003cdiv\u003e\n 這將創建一個名爲\u0026nbsp;project_name\u0026nbsp;的項目目錄。接下來,進入新創建的項目,使用下面的命令: \n \u003c/div\u003e \n \u003cpre\u003ecd scrapy_project\r\u003c/pre\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 控制項目 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n 您可以控制項目,並通過使用Scrapy工具,也創造了新的蜘蛛(spider),使用下面的命令進行管理: \n \u003c/div\u003e \n \u003cpre\u003escrapy genspider mydomain yiibai.com\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如:抓取等等的命令在 Scrapy 項目中的使用。這裏所有命令在接下來 Scrapy 項目內使用運行。 \n \u003c/div\u003e \n \u003cdiv\u003e\n Scrapy包含一些內置的命令,它可以用來爲項目。要查看可用命令的列表,請使用以下命令: \n \u003c/div\u003e \n \u003cpre\u003escrapy -h\r\u003c/pre\u003e \n \u003cdiv\u003e\n 當運行上面的命令,Scrapy將顯示如下面所列出可用命令的列表: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e fetch:\u0026nbsp;它使用Scrapy\u0026nbsp;downloader\u0026nbsp;提取的\u0026nbsp;URL。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e runspider:\u0026nbsp;它用於而無需創建一個項目運行自行包含蜘蛛(spider)。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e settings:\u0026nbsp;它規定了項目的設定值。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e shell:\u0026nbsp;這是一個給定URL的一個交互式模塊。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e startproject:\u0026nbsp;它創建了一個新的 Scrapy\u0026nbsp;項目。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e version:\u0026nbsp;它顯示Scrapy版本。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e view:\u0026nbsp;它使用Scrapy\u0026nbsp;downloader\u0026nbsp;提取\u0026nbsp;URL並顯示在瀏覽器中的內容。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 一些項目相關的命令,如下: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e crawl:\u0026nbsp;它是用來使用蜘蛛抓取數據; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e check:\u0026nbsp;它檢查項目並由\u0026nbsp;crawl\u0026nbsp;命令返回; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e list:\u0026nbsp;它顯示本項目中可用蜘蛛(spider)的列表; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e edit:\u0026nbsp;可以通過編輯器編輯蜘蛛; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e parse:它通過蜘蛛分析給定的URL; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e bench:\u0026nbsp;它是用來快速運行基準測試(基準講述每分鐘可被Scrapy抓取的頁面數量)。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 自定義項目命令 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 可以在Scrapy項目中通過COMMANDS_MODULE設置構建一個自定義項目命令。 \n \u003c/div\u003e \n \u003cpre\u003eCOMMANDS_MODULE = 'mycmd.commands'\r\u003c/pre\u003e \n \u003cdiv\u003e\n Scrapy命令可以通過使用\u0026nbsp;setup.py\u0026nbsp;文件中的\u0026nbsp;scrapy.commands\u0026nbsp;部分來添加,如下所示: \n \u003c/div\u003e \n \u003cpre\u003efrom setuptools import setup, find_packages\r\n\r\nsetup(name='scrapy-module_demo',\r\n entry_points={\r\n 'scrapy.commands': [\r\n 'cmd_demo=my_module.commands:CmdDemo',\r\n ],\r\n },\r\n)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面的代碼將在setup.py文件添加\u0026nbsp;cmd_demo\u0026nbsp;命令。 \n \u003c/div\u003e \n \u003cp\u003e \u003cbr\u003e \u003c/p\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2c:T317b,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n Spider是負責定義如何遵循通過網站的鏈接並提取網頁中的信息的類。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy默認的\u0026nbsp;Spider\u0026nbsp;如下: \n \u003c/div\u003e \n \u003ch3\u003e scrapy.Spider \u003c/h3\u003e \n \u003cdiv\u003e\n 它是所有其他的蜘蛛(spider)都必須繼承的類。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.Spider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示了 scrapy.Spider 類的字段: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 字段 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e name\u003cbr\u003e 這是\u0026nbsp;spider\u0026nbsp;的名字 \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e allowed_domains\u003cbr\u003e \n \u003cdiv\u003e\n 它是允許\u0026nbsp;spider\u0026nbsp;抓取域名稱的列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e start_urls\u003cbr\u003e \n \u003cdiv\u003e\n 這是供以後蜘蛛將開始抓取的URL列表的根 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e custom_settings\u003cbr\u003e \n \u003cdiv\u003e\n 這些設置在蜘蛛運行時會從項目範圍內覆蓋配置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e crawler\u003cbr\u003e \n \u003cdiv\u003e\n 它是鏈接到 spider 實例綁定的 Crawler 對象的屬性 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e settings\u003cbr\u003e \n \u003cdiv\u003e\n 這些是運行一個\u0026nbsp;spider\u0026nbsp;的設置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e logger\u003cbr\u003e \n \u003cdiv\u003e\n 它是用來發送日誌消息的 python 記錄器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 8 \u003c/td\u003e \n \u003ctd\u003e from_crawler(crawler,*args,**kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它是由\u0026nbsp;spider\u0026nbsp;創建的一個類方法。參數是: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e crawler:\u0026nbsp;抓取工具到\u0026nbsp;spider\u0026nbsp;實例將被綁定; \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e args(list):\u0026nbsp;這些參數傳遞給方法:\u0026nbsp;_init_(); \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e kwargs(dict):\u0026nbsp;這些關鍵字參數傳遞給方法:\u0026nbsp;_init_(). \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 9 \u003c/td\u003e \n \u003ctd\u003e start_requests()\u003cbr\u003e \n \u003cdiv\u003e\n 如果不指定特定的URL,蜘蛛會打開抓取,Scrapy調用start_requests()方法 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 10 \u003c/td\u003e \n \u003ctd\u003e make_requests_from_url(url)\u003cbr\u003e \n \u003cdiv\u003e\n 它是用於將URL網址轉換爲請求方法 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 11 \u003c/td\u003e \n \u003ctd\u003e parse(response)\u003cbr\u003e \n \u003cdiv\u003e\n 這個方法處理響應並返回廢棄數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 12 \u003c/td\u003e \n \u003ctd\u003e log(message[,level,component])\u003cbr\u003e \n \u003cdiv\u003e\n 這個方法會通過蜘蛛發送日誌記錄信息 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 13 \u003c/td\u003e \n \u003ctd\u003e closed(reason)\u003cbr\u003e \n \u003cdiv\u003e\n 這種方法在當蜘蛛關閉時調用 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e Spider參數 \u003c/h2\u003e \n \u003cdiv\u003e\n Spider\u0026nbsp;參數用於指定起始URL和使用帶有-a選項的抓取命令來傳遞,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003escrapy crawl first_scrapy -a group = accessories\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的代碼示例顯示蜘蛛是如何接收參數的: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\n\r\nclass FirstSpider(scrapy.Spider):\r\n name = \"first\"\r\n\r\n def __init__(self, group=None, *args, **kwargs):\r\n super(FirstSpider, self).__init__(*args, **kwargs)\r\n self.start_urls = [\"http://www.yiibai.com/group/%s\" % group]\r\u003c/pre\u003e \n \u003ch2\u003e 通用Spider \u003c/h2\u003e \n \u003cp\u003e 您可以使用通用蜘蛛來創建子類蜘蛛。他們的目的是要根據一定的規則來提取所有在網站上的所有鏈接的數據。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cdiv\u003e\n 我們假設項目有以下的字段: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.item import Item, Field\r\n\t\r\nclass First_scrapyItem(scrapy.Item):\r\n product_title = Field()\r\n product_link = Field()\r\n product_description = Field()\r\u003c/pre\u003e \n \u003ch2\u003e CrawlSpider \u003c/h2\u003e \n \u003cdiv\u003e\n CrawlSpider定義了一套規律可循的聯繫,並取消多個頁面。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.CrawlSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 以下是CrawlSpider類的屬性: \n \u003c/div\u003e \n \u003ch3\u003e rules \u003c/h3\u003e \n \u003cdiv\u003e\n 這是規則對象的列表,它定義了爬網程序如何抓取下面的鏈接。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 下面的表顯示了CrawlSpider類的規則: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 規則和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e LinkExtractor\u003cbr\u003e \n \u003cdiv\u003e\n 它指定蜘蛛如何跟隨鏈接和提取數據; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e callback\u003cbr\u003e \n \u003cdiv\u003e\n 它是在每一頁提取之後被調用;\u0026nbsp; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e follow\u003cbr\u003e \n \u003cdiv\u003e\n 它指定是否繼續跟蹤鏈接; \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch3\u003e parse_start_url(response) \u003c/h3\u003e \n \u003cp\u003e 它通過允許解析初步迴應返回項目或請求對象。 \u003c/p\u003e \n \u003cp\u003e 注意:\u0026nbsp;請務必重命名等函數解析而不是編寫規則,因爲解析函數用於CrawlSpider來實現它的邏輯。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cp\u003e 讓我們看看下面的例子開始演示蜘蛛爬行\u0026nbsp;example.com 首頁,使用\u0026nbsp;parse_items 方法收集所有頁面上的鏈接和詞組: \u003c/p\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.spiders import CrawlSpider, Rule\r\nfrom scrapy.linkextractors import LinkExtractor\r\n\r\nclass DemoSpider(CrawlSpider):\r\n name = \"demo\"\r\n allowed_domains = [\"www.yiibai.com\"]\r\n start_urls = [\"http://www.yiibai.com\"]\r\n\r\n rules = (\r\n Rule(LinkExtractor(allow =(), restrict_xpaths = (\"//div[@class = 'next']\",)), callback = \"parse_item\", follow = True),\r\n )\r\n\r\n def parse_item(self, response):\r\n item = DemoItem()\r\n item[\"product_title\"] = response.xpath(\"a/text()\").extract()\r\n item[\"product_link\"] = response.xpath(\"a/@href\").extract()\r\n item[\"product_description\"] = response.xpath(\"div[@class='desc']/text()\").extract()\r\n return items\r\u003c/pre\u003e \n \u003ch2\u003e XMLFeedSpider \u003c/h2\u003e \n \u003cdiv\u003e\n 它是從XML的Feed提取並遍歷節點的蜘蛛的基類。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.XMLFeedSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下表顯示了用於設置iterator和標記名稱的類屬性: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 屬性和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e iterator\u003cbr\u003e \n \u003cdiv\u003e\n 它定義將要使用的迭代器。它可以是iternodes,HTML或XML。默認爲:iternodes \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e itertag\u003cbr\u003e \n \u003cdiv\u003e\n 它使用節點名稱的字符串進行迭代 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e namespaces\u003cbr\u003e \n \u003cdiv\u003e\n 它是由(prefix,\u0026nbsp;uri)元組使用register_namespace()方法自動註冊命名空間的列表中定義 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e adapt_response(response)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收響應,並儘快在開始解析之前從蜘蛛中間件修改響應體 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e parse_node(response,selector)\u003cbr\u003e 它接收到響應和選擇器,在每個節點匹配提供標籤名時調用\u003cbr\u003e \n \u003cdiv\u003e\n 注意:如果不重寫此方法,蜘蛛將不起作用 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e process_results(response,results)\u003cbr\u003e \n \u003cdiv\u003e\n 它由蜘蛛返回結果和響應列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e CSVFeedSpider \u003c/h2\u003e \n \u003cdiv\u003e\n 它通過它的每行的迭代,收到一個CSV文件作爲響應,並調用\u0026nbsp;parse_row()\u0026nbsp;方法。它具有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.spiders.CSVFeedSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下表顯示了可設置關於CSV文件的選項: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 選項及說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e delimiter\u003cbr\u003e \n \u003cdiv\u003e\n 它是包含每個字段使用逗號(「,」)分隔的字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e quotechar\u003cbr\u003e \n \u003cdiv\u003e\n 這是一個包含每個字段使用引號('\"')字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e headers\u003cbr\u003e \n \u003cdiv\u003e\n 它是一個可從中可以提取字段語句的列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e parse_row(response,row)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收一個響應,並每一行使用報頭鍵 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cp\u003e CSVFeedSpider 示例: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.spiders import CSVFeedSpider\r\nfrom demoproject.items import DemoItem\r\n\r\nclass DemoSpider(CSVFeedSpider):\r\n name = \"demo\"\r\n allowed_domains = [\"www.yiibai.com\"]\r\n start_urls = [\"http://www.yiibai.com/feed.csv\"]\r\n delimiter = \";\"\r\n quotechar = \"'\"\r\n headers = [\"product_title\", \"product_link\", \"product_description\"]\r\n\r\n def parse_row(self, response, row):\r\n self.logger.info(\"This is row: %r\", row)\r\n\r\n item = DemoItem()\r\n item[\"product_title\"] = row[\"product_title\"]\r\n item[\"product_link\"] = row[\"product_link\"]\r\n item[\"product_description\"] = row[\"product_description\"]\r\n return item\r\u003c/pre\u003e \n \u003ch2\u003e SitemapSpider \u003c/h2\u003e \n \u003cp\u003e 站點地圖(\u003ca href=\"http://www.sitemaps.org/\"\u003esitemap\u003c/a\u003e)幫助蜘蛛通過 robots.txt 的定位網址並抓取網站。它有以下類: \u003c/p\u003e \n \u003cpre\u003eclass scrapy.spiders.SitemapSpider\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示了SitemapSpider的字段: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 字段及說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e sitemap_urls\u003cbr\u003e \n \u003cdiv\u003e\n 要抓取指向網站地圖的URL列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e sitemap_rules\u003cbr\u003e \n \u003cdiv\u003e\n 這是一個元組列表\u0026nbsp;(regex,\u0026nbsp;callback)\u0026nbsp;,其中,正則表達式是正則表達式,回調是用來處理的URL匹配的正則表達式 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e sitemap_follow\u003cbr\u003e \n \u003cdiv\u003e\n 這是網站地圖的正則表達式的跟蹤列表 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e sitemap_alternate_links\u003cbr\u003e \n \u003cdiv\u003e\n 指定要跟蹤一個URL備用鏈路 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cp\u003e SitemapSpider 示例: \u003c/p\u003e \n \u003cdiv\u003e\n 下面是\u0026nbsp;SitemapSpider\u0026nbsp;處理所有的網址: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/sitemap.xml\"]\r\n\r\n def parse(self, response):\r\n # You can scrap items here\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面是\u0026nbsp;SitemapSpider\u0026nbsp;處理某些URL與回調: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/sitemap.xml\"]\r\n rules = [\r\n (\"/item/\", \"parse_item\"),\r\n (\"/group/\", \"parse_group\"),\r\n ]\r\n\r\n def parse_item(self, response):\r\n # you can scrap item here\r\n\r\n def parse_group(self, response):\r\n # you can scrap group here \u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 下面的代碼顯示了跟蹤站點地圖,在 robots.txt 中的網址有\u0026nbsp;/sitemap_company: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/robots.txt\"]\r\n rules = [\r\n (\"/company/\", \"parse_company\"),\r\n ]\r\n sitemap_follow = [\"/sitemap_company\"]\r\n\r\n def parse_company(self, response):\r\n # you can scrap company here\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您甚至可以將\u0026nbsp;SitemapSpider\u0026nbsp;與其他網址相結合如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.spiders import SitemapSpider\r\n\r\nclass DemoSpider(SitemapSpider):\r\n urls = [\"http://www.yiibai.com/robots.txt\"]\r\n rules = [\r\n (\"/company/\", \"parse_company\"),\r\n ]\r\n\r\n other_urls = [\"http://www.yiibai.com/contact-us\"]\r\n\r\n def start_requests(self):\r\n requests = list(super(DemoSpider, self).start_requests())\r\n requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]\r\n return requests\r\n\r\n def parse_company(self, response):\r\n # you can scrap company here...\r\n\t\t\r\n def parse_other(self, response):\r\n # you can scrap other here...\u003c/pre\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2d:T155a,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n 當刮取網頁中的數據,需要通過使用XPath或CSS表達式來實現選擇器機制提取HTML源代碼的某些部分。選擇器是在Python語言的XML和LXML庫建成的 \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003cdiv\u003e\n 我們使用下面的代碼片段在本章中來定義選擇器不同的概念: \n \u003c/div\u003e \n \u003cpre\u003e\u0026lt;html\u0026gt;\r\n \u0026lt;head\u0026gt;\r\n \u0026lt;title\u0026gt;My Website\u0026lt;/title\u0026gt;\r\n \u0026lt;/head\u0026gt;\r\n \u0026lt;body\u0026gt;\r\n \u0026lt;span\u0026gt;Scrapy Hello world\u0026lt;/span\u0026gt;\r\n \u0026lt;div class='links'\u0026gt;\r\n \u0026lt;a href='one.html'\u0026gt;Link 1\u0026lt;img src='image1.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;a href='two.html'\u0026gt;Link 2\u0026lt;img src='image2.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;a href='three.html'\u0026gt;Link 3\u0026lt;img src='image3.jpg'/\u0026gt;\u0026lt;/a\u0026gt;\r\n \u0026lt;/div\u0026gt;\r\n \u0026lt;/body\u0026gt;\r\n\u0026lt;/html\u0026gt;\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 構造選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 可以通過\u0026nbsp;text\u0026nbsp;或\u0026nbsp;TextResponse\u0026nbsp;對象構造選擇器類的實例。根據所提供的輸入類型,選擇器選擇以下規則: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.selector import Selector\r\nfrom scrapy.http import HtmlResponse\r\u003c/pre\u003e \n \u003cdiv\u003e\n 使用上面的代碼,可以從文本建構如下: \n \u003c/div\u003e \n \u003cpre\u003eSelector(text=body).xpath('//span/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示的結果爲: \n \u003c/div\u003e \n \u003cpre\u003e[u'Hello world!!!']\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以從響應構建: \n \u003c/div\u003e \n \u003cpre\u003eresponse = HtmlResponse(url='http://yiibai.com', body=body)\r\nSelector(response=response).xpath('//span/text()').extract()\r\u003c/pre\u003e \n \u003cp\u003e 它顯示的結果爲: \u003c/p\u003e \n \u003cpre\u003e[u'Hello world!!!']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 使用上面的示例代碼片段,您可以構建XPath選擇\u0026nbsp;title\u0026nbsp;標籤定義的標題文本,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.selector.xpath('//title/text()')\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 現在,您可以通過使用 .extract()方法提取文本數據,如下所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//title/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將產生結果如下: \n \u003c/div\u003e \n \u003cpre\u003e[u'My Website']\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示所有元素的名稱,如下所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//div[@class=\"links\"]/a/text()').extract()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它提供的元素顯示如下: \n \u003c/div\u003e \n \u003cpre\u003eLink 1\r\nLink 2\r\nLink 3\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如果要提取的第一個元素,那麼使用\u0026nbsp;.extract_first()方法,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//div[@class=\"links\"]/a/text()').extract_first()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將顯示元素爲: \n \u003c/div\u003e \n \u003cpre\u003eLink 1\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 嵌套選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 使用上面的代碼,通過使用.xpath()方法可以嵌套選擇器來顯示頁面的鏈接和圖像源,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003elinks = response.xpath('//a[contains(@href, \"image\")]')\r\nfor index, link in enumerate(links):\r\n args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())\r\n print 'The link %d pointing to url %s and image %s' % args\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它將顯示的結果爲: \n \u003c/div\u003e \n \u003cpre\u003eLink 1 pointing to url [u'one.html'] and image [u'image1.jpg']\r\nLink 2 pointing to url [u'two.html'] and image [u'image2.jpg']\r\nLink 3 pointing to url [u'three.html'] and image [u'image3.jpg']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用正則表達式選擇器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e Scrapy\u0026nbsp;允許使用\u0026nbsp;.re()\u0026nbsp;方法正則表達式來提取數據。從上面的HTML代碼中可提取圖像名稱,如下圖所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;response.xpath('//a[contains(@href, \"image\")]/text()').re(r'Name:\\s*(.*)')\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面一行代碼顯示圖像的名稱爲: \n \u003c/div\u003e \n \u003cpre\u003e[u'Link 1',\r\n u'Link 2',\r\n u'Link 3']\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 用相對的XPaths \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 當您使用XPaths,它是從 / 開始工作的,嵌套選擇器和XPath都關聯到文件的絕對路徑,而不是選擇器的相對路徑。 \u003c/p\u003e \n \u003cdiv\u003e\n 如果想提取\u0026lt;p\u0026gt;元素,那麼首先獲得所有 div 元素: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;mydiv = response.xpath('//div')\r\u003c/pre\u003e \n \u003cp\u003e 接下來,可以在裏面提取所有 'P' 元素,在XPath前綴加上一個句點 .//p ,如下圖所示: \u003c/p\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;for p in mydiv.xpath('.//p').extract()\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用EXSLT擴展 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e EXSLT是一個社區它發出擴展XML文檔轉換爲XHTML文檔XSLT(可擴展樣式表語言轉換)。可以使用 EXSLT 擴展與 XPath 表達式來註冊名稱空間,如下列表中所示: \u003c/p\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 前綴用法 \n \u003c/div\u003e \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 命名空間 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e re\u003cbr\u003e \n \u003cdiv\u003e\n 正則表達式 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003ca href=\"http://exslt.org/regexp/index.html\"\u003ehttp://exslt.org/regular-expressions\u003c/a\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e set\u003cbr\u003e \n \u003cdiv\u003e\n 集合操作 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003ca href=\"http://exslt.org/set/index.html\"\u003ehttp://exslt.org/sets\u003c/a\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 您可以檢查在上一節中使用正則表達式提取數據的代碼格式。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 有一些關於 XPath 的提示,使用 XPath 與 Scrapy 選擇器時非常有用。欲瞭解更多信息,請點擊此 \n \u003ca href=\"https://www.yiibai.com/scrapy/xpth_tips.html\"\u003e鏈接\u003c/a\u003e。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2e:T841,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e\n Scrapy進程可通過使用蜘蛛提取來自網頁中的數據。Scrapy使用Item類生成輸出對象用於收刮數據。 \n\u003c/div\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 聲明項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cdiv\u003e\n 如下圖所示,您可以通過使用字段對象和類定義語法聲明項目: \n\u003c/div\u003e \n\u003cpre\u003eimport scrapy\r\nclass MyProducts(scrapy.Item):\r\n productName = Field()\r\n productLink = Field()\r\n imageURL = Field()\r\n price = Field()\r\n size = Field()\r\u003c/pre\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 項目字段 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cp\u003e 項目字段用於顯示每個字段的元數據。字段對象上的值沒有限制,可訪問元數據的鍵不包含的元數據的任何引用列表。字段對象用於指定所有字段元數據,您可以根據項目您的要求指定任何其他字段鍵。字段對象可以通過使用 Item.fields 屬性進行訪問。 \u003c/p\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 使用項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cp\u003e 當在使用項目工作時,可以定義一些常用功能。欲瞭解更多信息,請點擊此\u003ca href=\"https://www.yiibai.com/scrapy/working_with_items.html\"\u003e鏈接\u003c/a\u003e。 \u003c/p\u003e \n\u003ch2\u003e \n \u003cdiv\u003e\n 擴展項目 \n \u003c/div\u003e \u003c/h2\u003e \n\u003cdiv\u003e\n 項目可以從原始項目的子類聲明進行擴展。\u0026nbsp;例如: \n\u003c/div\u003e \n\u003cpre\u003eclass MyProductDetails(Product):\r\n original_rate = scrapy.Field(serializer=str)\r\n discount_rate = scrapy.Field()\r\u003c/pre\u003e \n\u003cdiv\u003e\n 可以通過使用現有的字段元數據添加更多的值,或者改變現有值來擴展,如下面的代碼: \n\u003c/div\u003e \n\u003cpre\u003eclass MyProductPackage(Product):\r\n name = scrapy.Field(Product.fields['name'], serializer=serializer_demo)\r\u003c/pre\u003e \n\u003ch2\u003e 項目對象 \u003c/h2\u003e \n\u003cdiv\u003e\n Item\u0026nbsp;對象可以通過使用以下類,它從指定的參數提供新的初始化項目: \n\u003c/div\u003e \n\u003cpre\u003eclass scrapy.item.Item([arg])\u0026nbsp;\u003c/pre\u003e \n\u003cp\u003e Item\u0026nbsp;提供了一個構造函數的副本,並由在\u0026nbsp;fields\u0026nbsp;中的項目提供額外的屬性。\u0026nbsp; \u003c/p\u003e \n\u003ch2\u003e 字段對象 \u003c/h2\u003e \n\u003cdiv\u003e\n 字段對象可以通過使用下面類中的Field類,不發出附加處理或屬性來指定: \n\u003c/div\u003e \n\u003cpre\u003eclass scrapy.item.Field([arg])\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"2f:T4449,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n 項目加載器提供了一個方便的方式來填補從網站上刮取的項目。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 聲明項目加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器的聲明類:Items。例如: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.loader import ItemLoader\r\nfrom scrapy.loader.processors import TakeFirst, MapCompose, Join\r\n\r\nclass DemoLoader(ItemLoader):\r\n\r\n default_output_processor = TakeFirst()\r\n\r\n title_in = MapCompose(unicode.title)\r\n title_out = Join()\r\n\r\n size_in = MapCompose(unicode.strip)\r\n\r\n # you can continue scraping here\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 在上面的代碼可以看到,輸入處理器使用 _id 作爲後綴以及輸出處理器聲明使用_out 作爲後綴聲明。ItemLoader.default_input_processor\u0026nbsp;和\u0026nbsp;ItemLoader.default_output_processor\u0026nbsp;屬性用於聲明默認輸入/輸出處理器。 \u003c/p\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 使用項目加載器來填充項目 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 要使用項目加載器,先用類似字典的對象,或項目使用\u0026nbsp;Loader.default_item_class\u0026nbsp;屬性指定\u0026nbsp;Item\u0026nbsp;類實例化。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以使用選擇器來收集值到項目加載器。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 可以在同一項目字段中添加更多的值,項目加載器將使用相應的處理程序來添加這些值。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 下面的代碼演示項目是如何使用項目加載器來填充: \n \u003c/div\u003e \n \u003cpre\u003efrom scrapy.loader import ItemLoader\r\nfrom demoproject.items import Demo\r\n\r\ndef parse(self, response):\r\n l = ItemLoader(item = Product(), response = response)\r\n l.add_xpath(\"title\", \"//div[@class='product_title']\")\r\n l.add_xpath(\"title\", \"//div[@class='product_name']\")\r\n l.add_xpath(\"desc\", \"//div[@class='desc']\")\r\n l.add_css(\"size\", \"div#size]\")\r\n l.add_value(\"last_updated\", \"yesterday\")\r\n return l.load_item()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 如上圖所示,有兩種不同的XPath,使用\u0026nbsp;add_xpath()方法從標題(title)字段提取: \n \u003c/div\u003e \n \u003cpre\u003e1. //div[@class=\"product_title\"] \r\n\r\n2. //div[@class=\"product_name\"]\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 此後,類似請求用於內容描述(desc)字段。size數據使用\u0026nbsp;add_css()方法提取和last_updated\u0026nbsp;使用add_value()方法使用值「yesterday」來填充。 \u003c/p\u003e \n \u003cdiv\u003e\n 完成所有收集數據的,調用\u0026nbsp;ItemLoader.load_item()\u0026nbsp;方法返回填充並使用\u0026nbsp;add_xpath(),add_css()和\u0026nbsp;dadd_value()方法提取數據項。 \n \u003c/div\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 輸入和輸出處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 一個項目加載器的各個字段包含一個輸入處理器和一個輸出處理器。 \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 當提取數據時,輸入處理器處理結果,交將結果存儲在數據加載器。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 接下來,收集數據後,調用\u0026nbsp;ItemLoader.load_item()\u0026nbsp;方法來獲得\u0026nbsp;Item\u0026nbsp;對象。 \n \u003c/div\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 最後,指定輸出處理器到該項目的結果。 \n \u003c/div\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003cdiv\u003e\n 下面的代碼演示針對特定字段如何調用輸入和輸出處理器: \n \u003c/div\u003e \n \u003cpre\u003el = ItemLoader(Product(), some_selector)\r\nl.add_xpath(\"title\", xpath1) # [1]\r\nl.add_xpath(\"title\", xpath2) # [2]\r\nl.add_css(\"title\", css) # [3]\r\nl.add_value(\"title\", \"demo\") # [4]\r\nreturn l.load_item() # [5]\r\u003c/pre\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e 第1行:\u0026nbsp;標題(title)的數據是從xpath1提取並通過輸入處理器,其結果被收集並存儲在\u0026nbsp;ItemLoader\u0026nbsp;中。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第2行:\u0026nbsp;同樣地,標題(title)從xpath2提取並通過相同的輸入處理器,其結果收集的數據加到[1]中。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第3行:\u0026nbsp;標題(title)被從css選擇萃取和通過相同的輸入處理器傳遞並將收集的數據結果加到[1]及[2]。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第4行:\u0026nbsp;接着,將「demo」值分配並傳遞到輸入處理器。 \u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e 第5行:\u0026nbsp;最後,數據是從所有字段內部收集並傳遞給輸出處理器,最終值將分配給項目。 \u003c/p\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 聲明輸入和輸出處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 輸入和輸出的處理器在項目加載器(ItemLoader\u0026nbsp;)定義聲明。除此之外,它們還可以在項目字段的元數據指定。 \u003c/p\u003e \n \u003cp\u003e 例如: \u003c/p\u003e \n \u003cpre\u003eimport scrapy\r\nfrom scrapy.loader.processors import Join, MapCompose, TakeFirst\r\nfrom w3lib.htmll import remove_tags\r\n\r\ndef filter_size(value):\r\n if value.isdigit():\r\n return value\r\n\r\nclass Item(scrapy.Item):\r\n name = scrapy.Field(\r\n input_processor = MapCompose(remove_tags),\r\n output_processor = Join(),\r\n )\r\n size = scrapy.Field(\r\n input_processor = MapCompose(remove_tags, filter_price),\r\n output_processor = TakeFirst(),\r\n )\r\u003c/pre\u003e \n \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader import ItemLoader\r\n\u0026gt;\u0026gt;\u0026gt; il = ItemLoader(item=Product())\r\n\u0026gt;\u0026gt;\u0026gt; il.add_value('title', [u'Hello', u'\u0026lt;strong\u0026gt;world\u0026lt;/strong\u0026gt;'])\r\n\u0026gt;\u0026gt;\u0026gt; il.add_value('size', [u'\u0026lt;span\u0026gt;100 kg\u0026lt;/span\u0026gt;'])\r\n\u0026gt;\u0026gt;\u0026gt; il.load_item()\r\u003c/pre\u003e \n \u003cdiv\u003e\n 它顯示的輸出結果如下: \n \u003c/div\u003e \n \u003cpre\u003e{'title': u'Hello world', 'size': u'100 kg'}\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 項目加載器上下文 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器上下文是輸入和輸出的處理器中共享的任意鍵值的字典。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如,假設有一個函數parse_length: \n \u003c/div\u003e \n \u003cpre\u003edef parse_length(text, loader_context):\r\n unit = loader_context.get('unit', 'cm')\r\n # You can write parsing code of length here \r\n return parsed_length\u0026nbsp;\u003c/pre\u003e \n \u003cp\u003e 通過接收loader_context參數,它告訴項目加載器可以收到項目加載器上下文。有幾種方法可以改變項目加載器上下文的值: \u003c/p\u003e \n \u003cul\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 修改當前的活動項目加載器上下文: \n \u003c/div\u003e \u003cpre\u003eloader = ItemLoader (product)\r\nloader.context [\"unit\"] = \"mm\"\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 在項目加載器實例中修改: \n \u003c/div\u003e \u003cpre\u003eloader = ItemLoader(product, unit=\"mm\")\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \n \u003cdiv\u003e\n 在加載器項目聲明與項目加載器上下文實例輸入/輸出處理器中修改: \n \u003c/div\u003e \u003cpre\u003eclass ProductLoader(ItemLoader):\r\n length_out = MapCompose(parse_length, unit=\"mm\")\r\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n \u003ch2\u003e ItemLoader對象 \u003c/h2\u003e \n \u003cdiv\u003e\n 它是一個對象,它返回一個新項加載器到填充給定項目。它有以下類: \n \u003c/div\u003e \n \u003cpre\u003eclass scrapy.loader.ItemLoader([item, selector, response, ]**kwargs)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面的表顯示 ItemReader 對象的參數: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 參數 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e item\u003cbr\u003e 它是通過\u0026nbsp;calling\u0026nbsp;add_xpath(),\u0026nbsp;add_css()\u0026nbsp;或\u0026nbsp;add_value()的填充項 \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e selector\u003cbr\u003e \n \u003cdiv\u003e\n 它用來從網站提取數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e response\u003cbr\u003e \n \u003cdiv\u003e\n 它是用\u0026nbsp;default_selector_class\u0026nbsp;來構造選擇器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 下表顯示項目加載器(ItemLoader)對象的方法: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 方法 \u0026amp; 描述 \u003c/th\u003e \n \u003cth\u003e 示例 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e get_value(value, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 由一個給定的處理器和關鍵字參數,該值在getValue()方法處理 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e \u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import TakeFirst\r\n \u0026gt;\u0026gt;\u0026gt; loader.get_value(u'title: demoweb', TakeFirst(), unicode.upper, re='title: (.+)')\r\n 'DEMOWEB`\r\n\t\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e add_value(field_name, value, *processors, **kwargs)\u003cbr\u003e 它首先通過get_value傳遞處理值,並增加到字段中 \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.add_value('title', u'DVD')\r\n loader.add_value('colors', [u'black', u'white'])\r\n loader.add_value('length', u'80')\r\n loader.add_value('price', u'2500')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e replace_value(field_name, value, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它用一個新值替換所收集的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.replace_value('title', u'DVD')\r\n loader.replace_value('colors', [u'black', u'white'])\r\n loader.replace_value('length', u'80')\r\n loader.replace_value('price', u'2500')\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e get_xpath(xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它用於由接到的XPath給處理器和關鍵字參數提取unicode字符串 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.get_xpath(\"//div[@class='item-name']\")\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.get_xpath(\"//div[@id='length']\", TakeFirst(), re=\"the length is (.*)\")\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e add_xpath(field_name, xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收XPath提取unicode字符串到字段中 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.add_xpath('name', '//div[@class=\"item-name\"]')\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.add_xpath('length', '//div[@id=\"length\"]', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e replace_xpath(field_name, xpath, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它使用XPath取換了從網站收集的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e # HTML code: \u0026lt;div class=\"item-name\"\u0026gt;DVD\u0026lt;/div\u0026gt;\r\n loader.replace_xpath('name', '//div[@class=\"item-name\"]')\r\n # HTML code: \u0026lt;div id=\"length\"\u0026gt;the length is 45cm\u0026lt;/div\u0026gt;\r\n loader.replace_xpath('length', '//div[@id=\"length\"]', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e get_css(css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它接收用於提取unicode字符串的CSS選擇器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.get_css(\"div.item-name\")\r\n loader.get_css(\"div#length\", TakeFirst(), re=\"the length is (.*)\")\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 8 \u003c/td\u003e \n \u003ctd\u003e add_css(field_name, css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它類似於add_value()方法,它增加CSS選擇器到字段中 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.add_css('name', 'div.item-name')\r\n loader.add_css('length', 'div#length', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 9 \u003c/td\u003e \n \u003ctd\u003e replace_css(field_name, css, *processors, **kwargs)\u003cbr\u003e \n \u003cdiv\u003e\n 它使用CSS選擇器取代了提取的數據 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader.replace_css('name', 'div.item-name')\r\n loader.replace_css('length', 'div#length', re='the length is (.*)')\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 10 \u003c/td\u003e \n \u003ctd\u003e load_item()\u003cbr\u003e \n \u003cdiv\u003e\n 當收集數據後,這個方法填充收集到數據的項目並返回 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e def parse(self, response):\r\n l = ItemLoader(item=Product(), response=response)\r\n l.add_xpath('title', '//div[@class=\"product_title\"]')\r\n loader.load_item()\r\n \u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 11 \u003c/td\u003e \n \u003ctd\u003e nested_xpath(xpath)\u003cbr\u003e \n \u003cdiv\u003e\n 它是通過XPath選擇器來創建嵌套加載器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader = ItemLoader(item=Item())\r\n loader.add_xpath('social', 'a[@class = \"social\"]/@href')\r\n loader.add_xpath('email', 'a[@class = \"email\"]/@href')\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 12 \u003c/td\u003e \n \u003ctd\u003e nested_css(css)\u003cbr\u003e \n \u003cdiv\u003e\n 它被用來創建一個CSS選擇器嵌套加載器 \n \u003c/div\u003e \u003c/td\u003e \n \u003ctd\u003e \u003cpre\u003e loader = ItemLoader(item=Item())\r\n loader.add_css('social', 'a[@class = \"social\"]/@href')\r\n loader.add_css('email', 'a[@class = \"email\"]/@href')\t\r\n\t\u003c/pre\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003cdiv\u003e\n 下表顯示項目加載器對象的屬性: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e 屬性 \u0026amp; 描述 \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e item\u003cbr\u003e \n \u003cdiv\u003e\n 它是項目加載器進行解析的對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e context\u003cbr\u003e \n \u003cdiv\u003e\n 這是項目加載器是活躍的當前上下文 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e default_item_class\u003cbr\u003e \n \u003cdiv\u003e\n 如果在構造沒有給出,它用來表示項 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e default_input_processor\u003cbr\u003e \n \u003cdiv\u003e\n 不指定輸入處理器中的字段,只有一個用於其默認輸入處理器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e default_output_processor\u003cbr\u003e \n \u003cdiv\u003e\n 不指定輸出處理器中的字段,只有一個用於其默認的輸出處理器 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 6 \u003c/td\u003e \n \u003ctd\u003e default_selector_class\u003cbr\u003e \n \u003cdiv\u003e\n 如果它沒有在構造給定,它是使用來構造選擇器的一個類 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 7 \u003c/td\u003e \n \u003ctd\u003e selector\u003cbr\u003e \n \u003cdiv\u003e\n 它是一個用來從站點提取數據的對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 嵌套加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cp\u003e 這是使用從文檔解析分段的值來創建嵌套加載器。如果不創建嵌套裝載器,需要爲您想提取的每個值指定完整的XPath或CSS。 \u003c/p\u003e \n \u003cdiv\u003e\n 例如,假設要從一個標題頁中提取數據: \n \u003c/div\u003e \n \u003cpre\u003e\u0026lt;header\u0026gt;\r\n \u0026lt;a class=\"social\" href=\"http://facebook.com/whatever\"\u0026gt;facebook\u0026lt;/a\u0026gt;\r\n \u0026lt;a class=\"social\" href=\"http://twitter.com/whatever\"\u0026gt;twitter\u0026lt;/a\u0026gt;\r\n \u0026lt;a class=\"email\" href=\"mailto:someone@example.com\"\u0026gt;send mail\u0026lt;/a\u0026gt;\r\n\u0026lt;/header\u0026gt;\r\u003c/pre\u003e \n \u003cdiv\u003e\n 接下來,您可以通過添加相關的值到頁眉來創建頭選擇器嵌套裝載器: \n \u003c/div\u003e \n \u003cpre\u003eloader = ItemLoader(item=Item())\r\nheader_loader = loader.nested_xpath('//header')\r\nheader_loader.add_xpath('social', 'a[@class = \"social\"]/@href')\r\nheader_loader.add_xpath('email', 'a[@class = \"email\"]/@href')\r\nloader.load_item()\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 重用和擴展項目加載器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 項目加載器的設計以緩解維護,當要獲取更多的蜘蛛時項目變成一個根本的問題。 \n \u003c/div\u003e \n \u003cp\u003e 舉例來說,假設一個網站自己的產品名稱是由三條短線封閉的(例如:\u0026nbsp;---DVD---)。\u0026nbsp;您可以通過重複使用默認產品項目加載器,如果你不希望它在最終產品名稱所示,下面的代碼刪除這些破折號: \u003c/p\u003e \n \u003cpre\u003efrom scrapy.loader.processors import MapCompose\r\nfrom demoproject.ItemLoaders import DemoLoader\r\n\r\ndef strip_dashes(x):\r\n return x.strip('-')\r\n\r\nclass SiteSpecificLoader(DemoLoader):\r\n title_in = MapCompose(strip_dashes, DemoLoader.title_in)\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 可用內置處理器 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 以下是一些常用的內置處理器: \n \u003c/div\u003e \n \u003cul\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.Identity \u003c/p\u003e \n \u003cdiv\u003e\n 它返回原始的值而並不修改它。\u0026nbsp;例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import Identity\r\n\u0026gt;\u0026gt;\u0026gt; proc = Identity()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\n['a', 'b', 'c']\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.TakeFirst \u003c/p\u003e \n \u003cdiv\u003e\n 它返回一個值來自收到列表的值即非空/非null值。\u0026nbsp;例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import TakeFirst\r\n\u0026gt;\u0026gt;\u0026gt; proc = TakeFirst()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['', 'a', 'b', 'c'])\r\n'a'\r\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.Join(separator = u' ') \u003c/p\u003e \n \u003cdiv\u003e\n 它返回附連到分隔符的值。默認的分隔符是\u0026nbsp;u'',這相當於於\u0026nbsp;u'\u0026nbsp;'.join\u0026nbsp;的功能。例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import Join\r\n\u0026gt;\u0026gt;\u0026gt; proc = Join()\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\nu'a b c'\r\n\u0026gt;\u0026gt;\u0026gt; proc = Join('\u0026lt;br\u0026gt;')\r\n\u0026gt;\u0026gt;\u0026gt; proc(['a', 'b', 'c'])\r\nu'a\u0026lt;br\u0026gt;b\u0026lt;br\u0026gt;c'\u003c/pre\u003e \u003c/li\u003e \n \u003cli\u003e \u003cp\u003e class scrapy.loader.processors.SelectJmes(json_path) \u003c/p\u003e \n \u003cdiv\u003e\n 此類查詢使用提供JSON路徑值,並返回輸出。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; from scrapy.loader.processors import SelectJmes, Compose, MapCompose\r\n\u0026gt;\u0026gt;\u0026gt; proc = SelectJmes(\"hello\")\r\n\u0026gt;\u0026gt;\u0026gt; proc({'hello': 'scrapy'})\r\n'scrapy'\r\n\u0026gt;\u0026gt;\u0026gt; proc({'hello': {'scrapy': 'world'}})\r\n{'scrapy': 'world'}\r\u003c/pre\u003e \n \u003cdiv\u003e\n 下面是一個查詢通過導入JSON值的代碼: \n \u003c/div\u003e \u003cpre\u003e\u0026gt;\u0026gt;\u0026gt; import json\r\n\u0026gt;\u0026gt;\u0026gt; proc_single_json_str = Compose(json.loads, SelectJmes(\"hello\"))\r\n\u0026gt;\u0026gt;\u0026gt; proc_single_json_str('{\"hello\": \"scrapy\"}')\r\nu'scrapy'\r\n\u0026gt;\u0026gt;\u0026gt; proc_json_list = Compose(json.loads, MapCompose(SelectJmes('hello')))\r\n\u0026gt;\u0026gt;\u0026gt; proc_json_list('[{\"hello\":\"scrapy\"}, {\"world\":\"env\"}]')\r\n[u'scrapy']\u003c/pre\u003e \u003c/li\u003e \n \u003c/ul\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"30:T18f5,"])</script><script>self.__next_f.push([1,"\u003cdiv\u003e \n \u003cdiv\u003e\n Scrapy\u0026nbsp;shell\u0026nbsp;可用於抓取數據並提示錯誤代碼,而無需使用蜘蛛。\u0026nbsp;Scrapy\u0026nbsp;shell的主要目的是測試所提取的代碼,XPath或CSS表達式。它還用來從中指定刮取數據的網頁。 \n \u003c/div\u003e \n\u003c/div\u003e \n\u003cdiv\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 配置Shell \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n shell\u0026nbsp;可以通過安裝\u0026nbsp; \n \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e(用於交互式計算)控制檯,它是強大的交互式的Shell,提供自動完成,彩色輸出等功能。 \n \u003c/div\u003e \n \u003cp\u003e 如果您在UNIX平臺上工作,那麼最好安裝 IPython。\u0026nbsp;如果有IPython的無法訪問,您也可以使用\u003ca href=\"http://www.bpython-interpreter.org/\"\u003ebpython\u003c/a\u003e。 \u003c/p\u003e \n \u003cdiv\u003e\n 您可以通過設置\u0026nbsp;SCRAPY_PYTHON_SHELL 環境變量或者在 scrapy.cfg 文件中定義配置\u0026nbsp;Shell,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e[settings]\r\nshell = bpython\r\u003c/pre\u003e \n \u003ch2\u003e 啓動Shell \u003c/h2\u003e \n \u003cdiv\u003e\n Scrapy\u0026nbsp;shell\u0026nbsp;可以用下面的命令來啓動: \n \u003c/div\u003e \n \u003cpre\u003escrapy shell \u0026lt;url\u0026gt;\r\u003c/pre\u003e \n \u003cdiv\u003e\n url 是指定爲需要進行數據抓取的URL \n \u003c/div\u003e \n \u003ch2\u003e 使用Shell \u003c/h2\u003e \n \u003cdiv\u003e\n shell提供一些附加快捷方式和Scrapy對象,如下所述: \n \u003c/div\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 可用快捷方式 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n shell提供可在項目中使用的快捷方式如下: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 快捷方式和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e shelp()\u003cbr\u003e \n \u003cdiv\u003e\n 它提供了可用對象和快捷方式的幫助選項 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e fetch(request_or_url)\u003cbr\u003e \n \u003cdiv\u003e\n 它會從請求或URL的響應收集相關對象可能的更新 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e view(response)\u003cbr\u003e 可以在本地瀏覽器查看特定請求的響應,觀察和正確顯示外部鏈接,追加基本標籤到響應正文。 \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch3\u003e \n \u003cdiv\u003e\n 可用Scrapy對象 \n \u003c/div\u003e \u003c/h3\u003e \n \u003cdiv\u003e\n shell在項目中提供以下可用Scrapy對象: \n \u003c/div\u003e \n \u003ctable\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003cth\u003e S.N. \u003c/th\u003e \n \u003cth\u003e \n \u003cdiv\u003e\n 對象和說明 \n \u003c/div\u003e \u003c/th\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1 \u003c/td\u003e \n \u003ctd\u003e crawler\u003cbr\u003e \n \u003cdiv\u003e\n 它指定當前爬行對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2 \u003c/td\u003e \n \u003ctd\u003e spider\u003cbr\u003e \n \u003cdiv\u003e\n 如果對於當前網址沒有蜘蛛,那麼它將通過定義新的蜘蛛處理URL或蜘蛛對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3 \u003c/td\u003e \n \u003ctd\u003e request\u003cbr\u003e \n \u003cdiv\u003e\n 它指定了最後採集頁面請求對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 4 \u003c/td\u003e \n \u003ctd\u003e response\u003cbr\u003e \n \u003cdiv\u003e\n 它指定了最後採集頁面響應對象 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 5 \u003c/td\u003e \n \u003ctd\u003e settings\u003cbr\u003e \n \u003cdiv\u003e\n 它提供當前Scrapy設置 \n \u003c/div\u003e \u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n \u003c/table\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n Shell會話示例 \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 讓我們試着刮取 scrapy.org 網站,然後開始從 yiibai.com 抓取數據,如下所述: \n \u003c/div\u003e \n \u003cdiv\u003e\n 在繼續之前,我們將首先啓動shell,執行如下面的命令: \n \u003c/div\u003e \n \u003cpre\u003escrapy shell 'http://scrapy.org' --nolog\r\u003c/pre\u003e \n \u003cdiv\u003e\n 當使用上面的URL,Scrapy將顯示可用的對象: \n \u003c/div\u003e \n \u003cpre\u003e[s] Available Scrapy objects:\r\n[s] crawler \r\n[s] item {}\r\n[s] request \r\n[s] response \u0026lt;200 http://scrapy.org\u0026gt;\r\n[s] settings \r\n[s] spider \r\n[s] Useful shortcuts:\r\n[s] shelp() Provides available objects and shortcuts with help option\r\n[s] fetch(req_or_url) Collects the response from the request or URL and associated objects will get update\r\n[s] view(response) View the response for the given request\r\u003c/pre\u003e \n \u003cdiv\u003e\n 接着,對象的工作開始,如下所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; response.xpath('//title/text()').extract_first()\r\nu'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'\r\n\r\n\u0026gt;\u0026gt; fetch(\"http://reddit.com\")\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n[s] item {}\r\n[s] request \r\n[s] response \u0026lt;200 https://www.yiibai.com/\u0026gt;\r\n[s] settings \r\n[s] spider \r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\r\n\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'reddit: the front page of the internet']\r\n\r\n\u0026gt;\u0026gt; request = request.replace(method=\"POST\")\r\n\r\n\u0026gt;\u0026gt; fetch(request)\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n...\r\u003c/pre\u003e \n \u003ch2\u003e \n \u003cdiv\u003e\n 從Spider檢查響應調用Shell \n \u003c/div\u003e \u003c/h2\u003e \n \u003cdiv\u003e\n 您可以檢查它是由蜘蛛處理的響應,只有期望得到的響應。 \n \u003c/div\u003e \n \u003cdiv\u003e\n 例如: \n \u003c/div\u003e \n \u003cpre\u003eimport scrapy\r\nclass SpiderDemo(scrapy.Spider):\r\n name = \"spiderdemo\"\r\n start_urls = [\r\n \"http://yiibai.com\",\r\n \"http://yiibai.org\",\r\n \"http://yiibai.net\",\r\n ]\r\n\r\n def parse(self, response):\r\n # You can inspect one specific response\r\n if \".net\" in response.url:\r\n from scrapy.shell import inspect_response\r\n inspect_response(response, self)\r\u003c/pre\u003e \n \u003cdiv\u003e\n 正如上面的代碼所示,可以從蜘蛛調用shell,通過使用下面的函數來檢查響應: \n \u003c/div\u003e \n \u003cpre\u003escrapy.shell.inspect_response\r\u003c/pre\u003e \n \u003cdiv\u003e\n 現在運行的蜘蛛,應該會得到如下界面: \n \u003c/div\u003e \n \u003cpre\u003e2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n2016-02-08 18:15:20-0400 [scrapy] DEBUG: Crawled (200) (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \r\n...\r\n\r\n\u0026gt;\u0026gt; response.url\r\n'http://yiibai.org'\r\u003c/pre\u003e \n \u003cdiv\u003e\n 您可以使用下面的代碼檢查提取的代碼是否正常工作: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; response.xpath('//div[@class=\"val\"]')\r\nIt displays the output as\r\n[]\r\u003c/pre\u003e \n \u003cdiv\u003e\n 上面一行只顯示空白輸出。現在可以調用 shell 來檢查響應,如下圖所示: \n \u003c/div\u003e \n \u003cpre\u003e\u0026gt;\u0026gt; view(response)\r\nIt displays the response as\r\nTrue\u003c/pre\u003e \n\u003c/div\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"31:T12ab,"])</script><script>self.__next_f.push([1,"\u003cp\u003eSpider定義從提取數據的初始 \u003cem\u003eURL\u003c/em\u003e,如何遵循分頁鏈接以及如何提取和分析在 \u003cem\u003eitems.py\u003c/em\u003e 定義字段的類。\u003cem\u003eScrapy\u003c/em\u003e 提供了不同類型的蜘蛛,每個都給出了一個具體的目的。\u003c/p\u003e \n\u003cp\u003e在 first_scrapy/spiders 目錄下創建了一個叫作 「first_spider.py」 文件,在這裏可以告訴 \u003cem\u003escrapy\u003c/em\u003e 。要如何查找確切數據,這裏必須要定義一些屬性:\u003c/p\u003e \n\u003cul\u003e \n \u003cli\u003e\u003cp\u003ename: 它定義了蜘蛛的唯一名稱;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003eallowed_domains: 它包含了蜘蛛抓取的基本URL;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003estart-urls: 蜘蛛開始爬行的URL列表;\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003eparse(): 這是提取並解析刮下數據的方法;\u003c/p\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003cp\u003e下面的代碼演示了蜘蛛代碼的樣子:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e# -*- coding: utf-8 -*-\r\n\r\n# Define here the models for your scraped items\r\n#\r\n# See documentation in:\r\n# http://doc.scrapy.org/en/latest/topics/items.html\r\n\r\nimport scrapy\r\n\r\nclass firstSpider(scrapy.Spider):\r\n name = \"first\"\r\n allowed_domains = [\"yiibai.com\"]\r\n start_urls = [\r\n \"http://www.yiibai.com/scrapy/scrapy_create_project.html\",\r\n \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n ]\r\n\r\n def parse(self, response):\r\n filename = response.url.split(\"/\")[-1]\r\n print 'Curent URL =\u0026gt; ', filename\r\n with open(filename, 'wb') as f:\r\n f.write(response.body)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e執行結果如下所示 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy crawl first\r\n2016-10-03 10:40:10 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 10:40:10 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'first_scrapy'}\r\n2016-10-03 10:40:10 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.logstats.LogStats',\r\n 'scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 10:40:11 [scrapy] INFO: Spider opened\r\n2016-10-03 10:40:11 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_create_project.html\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\nCurent URL =\u0026gt; scrapy_create_project.html\r\nCurent URL =\u0026gt; scrapy_environment.html\r\n2016-10-03 10:40:12 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 10:40:12 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 2, 40, 12, 98000),\r\n 'log_count/DEBUG': 4,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 2, 40, 11, 614000)}\r\n2016-10-03 10:40:12 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"32:Tfa1,"])</script><script>self.__next_f.push([1,"\u003cp\u003e要執行蜘蛛抓取數據,在 \u003cem\u003efirst_scrapy\u003c/em\u003e 目錄中運行以下命令: \u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy crawl first\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e在這裏,\u003cem\u003efirst\u003c/em\u003e 是創建蜘蛛時指定的蜘蛛名稱。\u003c/p\u003e \n\u003cp\u003e當蜘蛛開始抓取後,可以看到如下面的輸出:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy crawl first\r\n2016-10-03 10:40:10 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 10:40:10 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'first_scrapy'}\r\n2016-10-03 10:40:10 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.logstats.LogStats',\r\n 'scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 10:40:11 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 10:40:11 [scrapy] INFO: Spider opened\r\n2016-10-03 10:40:11 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_create_project.html\u0026gt; (referer: None)\r\n2016-10-03 10:40:11 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\nCurent URL =\u0026gt; scrapy_create_project.html\r\nCurent URL =\u0026gt; scrapy_environment.html\r\n2016-10-03 10:40:12 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 10:40:12 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 2, 40, 12, 98000),\r\n 'log_count/DEBUG': 4,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 2, 40, 11, 614000)}\r\n2016-10-03 10:40:12 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e正如你在輸出中看到的, 每個URL有一個日誌行,其中(引用:None)表示,網址是起始網址,它沒有引用。接下來,應該看到有兩個名爲 \u003cem\u003escrapy_environment.html\u003c/em\u003e和 \u003cem\u003escrapy_environment.html\u003c/em\u003e 的文件在 first_scrapy 這個目錄中有被創建。\u003cbr\u003e如下所示 -\u003cbr\u003e\u003cimg src=\"https://asset.1ju.org/cmsstatic/scrapy-3.png\" alt=\"Scrapy執行爬行捉取\"\u003e\u003c/p\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"33:T1bb4,"])</script><script>self.__next_f.push([1,"\u003cp\u003e從網頁中提取數據,Scrapy 使用基於 \u003ca href=\"https://www.w3.org/TR/xpath/\"\u003eXPath\u003c/a\u003e 和 \u003ca href=\"https://www.w3.org/TR/selectors/\"\u003eCSS\u003c/a\u003e 表達式的技術叫做選擇器。以下是 XPath 表達式的一些例子:\u003c/p\u003e \n\u003cp\u003e/html/head/title:\u003cbr\u003e這將選擇 HTML 文檔中的 \u0026lt;head\u0026gt; 元素中的 \u0026lt;title\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e/html/head/title/text(): 這將選擇 \u0026lt;title\u0026gt; 元素中的文本。\u003c/p\u003e \n\u003cp\u003e//td: 這將選擇所有的 \u0026lt;td\u0026gt; 元素。\u003c/p\u003e \n\u003cp\u003e//div[\u003ca href=\"https://github.com/class\" title=\"@class\" class=\"at-link\"\u003e@class\u003c/a\u003e=」slice」]: 選擇 div 包含一個屬性 class=」slice」 的所有元素。\u003c/p\u003e \n\u003cp\u003e選擇器有四個基本的方法,如下所示:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e方法 \u0026amp; 描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003eextract()\u003c/td\u003e \n \u003ctd\u003e它返回一個unicode字符串以及所選數據\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ere()\u003c/td\u003e \n \u003ctd\u003e它返回Unicode字符串列表,當正則表達式被賦予作爲參數時提取\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003expath()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定XPath表達式參數選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003ecss()\u003c/td\u003e \n \u003ctd\u003e它返回選擇器列表,它代表由指定CSS表達式作爲參數所選擇的節點。\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003ch2\u003e在Shell中使用選擇器\u003c/h2\u003e \n\u003cp\u003e若要演示選擇器在內置Scrapy Shell 中,必須要在您的系統中安裝 \u003ca href=\"http://ipython.org/\"\u003eIPython\u003c/a\u003e。 這裏最重要的是,在運行時網址應包含Scrapy引號之內; 否則使用的 URL 「\u0026amp;」 字符將不起作用。 可以通過在該項目的頂級目錄中,使用下面的命令啓動一個 shell:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003escrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003eshell 執行後結果如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eD:first_scrapy\u0026gt;scrapy shell \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n2016-10-03 11:45:08 [scrapy] INFO: Scrapy 1.1.2 started (bot: first_scrapy)\r\n2016-10-03 11:45:08 [scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'first_scrapy.spiders', 'ROBOTSTXT_OBEY': True, 'DUPEFILTER_CLASS': 'scrapy.dupefilters.BaseDupeFilter', 'SPIDER_MODULES': ['first_scrapy.spiders'], 'BOT_NAME': 'first_scrapy', 'LOGSTATS_INTERVAL': 0}\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled extensions:\r\n['scrapy.extensions.telnet.TelnetConsole',\r\n 'scrapy.extensions.corestats.CoreStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled downloader middlewares:\r\n['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',\r\n 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',\r\n 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',\r\n 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',\r\n 'scrapy.downloadermiddlewares.retry.RetryMiddleware',\r\n 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',\r\n 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',\r\n 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',\r\n 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',\r\n 'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware',\r\n 'scrapy.downloadermiddlewares.stats.DownloaderStats']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled spider middlewares:\r\n['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',\r\n 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',\r\n 'scrapy.spidermiddlewares.referer.RefererMiddleware',\r\n 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',\r\n 'scrapy.spidermiddlewares.depth.DepthMiddleware']\r\n2016-10-03 11:45:08 [scrapy] INFO: Enabled item pipelines:\r\n[]\r\n2016-10-03 11:45:08 [scrapy] DEBUG: Telnet console listening on 127.0.0.1:6023\r\n2016-10-03 11:45:08 [scrapy] INFO: Spider opened\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/robots.txt\u0026gt; (referer: None)\r\n2016-10-03 11:45:09 [scrapy] DEBUG: Crawled (200) \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt; (referer: None)\r\n[s] Available Scrapy objects:\r\n[s] crawler \u0026lt;scrapy.crawler.Crawler object at 0x00000000042E3E80\u0026gt;\r\n[s] item {}\r\n[s] request \u0026lt;GET http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] response \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n[s] settings \u0026lt;scrapy.settings.Settings object at 0x00000000042E3E10\u0026gt;\r\n[s] spider \u0026lt;firstSpider 'first' at 0x47f9f28\u0026gt;\r\n[s] Useful shortcuts:\r\n[s] shelp() Shell help (print this help)\r\n[s] fetch(req_or_url) Fetch request (or URL) and update local objects\r\n[s] view(response) View response in a browser\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e當 shell 加載後,可以分別通過使用 response.body 和 response.header 訪問主體或頭信息。同樣,也可以通過使用 response.selector.xpath()或 response.selector.css()運行查詢的響應結果。\u003c/p\u003e \n\u003cp\u003e例如:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; response.xpath('//title')\r\n[\u0026lt;Selector xpath='//title' data=u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title').extract()\r\n[u'\u0026lt;title\u0026gt;Scrapyu5b89u88c5 - Scrapyu6559u7a0b\u0026lt;/title\u0026gt;']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()')\r\n[\u0026lt;Selector xpath='//title/text()' data=u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b'\u0026gt;]\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').extract()\r\n[u'Scrapyu5b89u88c5 - Scrapyu6559u7a0b']\r\n\u0026gt;\u0026gt;\u0026gt; response.xpath('//title/text()').re('(w+):')\r\n[]\r\n\u0026gt;\u0026gt;\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e提取數據\u003c/h2\u003e \n\u003cp\u003e從一個普通的HTML網站提取數據,查看該網站得到的 XPath 的源代碼。檢測後,可以看到數據將在UL標籤,並選擇 li 標籤中的 元素。\u003c/p\u003e \n\u003cp\u003e代碼的下面行顯示了不同類型的數據的提取:\u003c/p\u003e \n\u003cp\u003e選擇 li 標籤內的數據:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li')\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇描述:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站標題:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/text()').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e對於選擇網站的鏈接:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eresponse.xpath('//ul/li/a/@href').extract()\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e下面的代碼用於演示上述提取的用法:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\n\r\nclass MyprojectSpider(scrapy.Spider):\r\n name = \"project\"\r\n allowed_domains = [\"dmoz.org\"]\r\n start_urls = [\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/\",\r\n \"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/\"\r\n ]\r\n\r\n def parse(self, response):\r\n for sel in response.xpath('//ul/li'):\r\n title = sel.xpath('a/text()').extract()\r\n link = sel.xpath('a/@href').extract()\r\n desc = sel.xpath('text()').extract()\r\n print title, link, desc\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"34:T3db5,"])</script><script>self.__next_f.push([1,"\u003cp\u003e項目(Item)對象是Python中的常規的字典類型。我們可以用下面的語法來訪問類的屬性:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt; item = YiibaiItem()\r\n\u0026gt;\u0026gt;\u0026gt; item['title'] = 'sample title'\r\n\u0026gt;\u0026gt;\u0026gt; item['title']\r\n'sample title'\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e添加上述代碼到下面的例子中:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e# -*- coding: utf-8 -*-\r\n\r\n# Define here the models for your scraped items\r\n#\r\n# See documentation in:\r\n# http://doc.scrapy.org/en/latest/topics/items.html\r\n\r\nimport scrapy\r\n\r\n\r\nfrom first_scrapy.items import YiibaiItem\r\n\r\nclass firstSpider(scrapy.Spider):\r\n name = \"first\"\r\n allowed_domains = [\"yiibai.com\"]\r\n start_urls = [\r\n \"http://www.yiibai.com/scrapy/scrapy_create_project.html\",\r\n \"http://www.yiibai.com/scrapy/scrapy_environment.html\"\r\n ]\r\n\r\n def parse(self, response):\r\n # 所有教程名稱及鏈接 ...\r\n for sel in response.xpath('//ul/li'):\r\n item = YiibaiItem()\r\n item['title'] = sel.xpath('a/text()').extract()\r\n item['link'] = sel.xpath('a/@href').extract()\r\n item['desc'] = sel.xpath('text()').extract()\r\n yield item\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e因此,上述蜘蛛的部分輸出結果是:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/python3/'],\r\n 'title': [u'Python3u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/php7/'],\r\n 'title': [u'PHP7u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/excel/'],\r\n 'title': [u'Excelu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/uml/'],\r\n 'title': [u'UML']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/socket/'],\r\n 'title': [u'Socketu7f16u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/html/radius/'],\r\n 'title': [u'Radiusu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/nodejs/'],\r\n 'title': [u'Node.jsu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/svn/'],\r\n 'title': [u'SVNu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/git/'],\r\n 'title': [u'Gitu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/makefile/'],\r\n 'title': [u'Makefile']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix/'],\r\n 'title': [u'Unix']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix_commands/'],\r\n 'title': [u'Linux/Unixu547du4ee4']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/unix_system_calls/'],\r\n 'title': [u'Unix/Linuxu7cfbu7edfu8c03u7528']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/shell/'],\r\n 'title': [u'Shell']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/drools/'],\r\n 'title': [u'Droolsu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/linq/'],\r\n 'title': [u'LinQu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/wcf/'],\r\n 'title': [u'WCFu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mysql/'],\r\n 'title': [u'MySQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/plsql/'],\r\n 'title': [u'PL/SQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/postgresql/'],\r\n 'title': [u'PostgreSQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mongodb/'],\r\n 'title': [u'MongoDBu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sqlite/'],\r\n 'title': [u'SQLiteu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/db2/'],\r\n 'title': [u'DB2u6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/redis/'],\r\n 'title': [u'Redisu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/memcached/'],\r\n 'title': [u'Memcachedu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/access/'],\r\n 'title': [u'Accessu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sql/'],\r\n 'title': [u'SQLu6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/sql_server/'],\r\n 'title': [u'SQL Serveru6559u7a0b']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/java/'],\r\n 'title': [u'Java']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/python/'],\r\n 'title': [u'Python']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/mysql/'],\r\n 'title': [u'MySQL']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/articles'],\r\n 'title': [u'u6700u65b0u6587u7ae0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '],\r\n 'link': [u'http://www.yiibai.com/login/byqq'],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ',\r\n u'\r\n ',\r\n u'\r\n',\r\n u'\r\n ',\r\n u'\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n ', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5xa0', u'\u0026amp;amd64\r\n '],\r\n 'link': [u'http://sourceforge.net/projects/pywin32/'],\r\n 'title': [u'pywin32']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5 Python2.7.9 u4ee5u4e0bu7684xa0',\r\n u'xa0u6216u8005u4e0bu8f7du5730u5740uff1axa0',\r\n u' \r\n '],\r\n 'link': [u'https://pip.pypa.io/en/latest/installing/',\r\n u'https://pypi.python.org/pypi/setuptools#files',\r\n u'https://pypi.python.org/pypi/setuptools#files'],\r\n 'title': [u'pip', u'https://pypi.python.org/pypi/setuptools#files', u'xa0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u60a8u53efu4ee5u901au8fc7u4f7fu7528u4ee5u4e0bu547du4ee4u6765u68c0u67e5 pip u7248u672cuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5twisteduff0cu4e0bu8f7du5730u5740 -',\r\n u' \r\n '],\r\n 'link': [u'https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0'],\r\n 'title': [u'https://pypi.python.org/packages/2.7/T/Twisted/Twisted-13.0.0.win32-py2.7.msi#md5=c2d453a344f56cf6f77204c5769288c0']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5xa0zope u63a5u53e3uff1a',\r\n u'xa0u9009u62e9u5012u6570u7b2cu4e8cu4e2axa0',\r\n u'xa0',\r\n u'\r\n '],\r\n 'link': [u'https://pypi.python.org/pypi/zope.interface/4.1.0',\r\n u'https://pypi.python.org/packages/2.7/z/zope.interface/zope.interface-4.1.0.win32-py2.7.exe#md5=c0100a3cd6de6ecc3cd3b4d678ec7931'],\r\n 'title': [u'https://pypi.python.org/pypi/zope.interface/4.1.0',\r\n u'zope.interface-4.1.0.win32-py2.7.exe']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5 lxml uff0cu7248u672cu8981u9009u5bf9u5e94u7cfbu7edfuff0cu9519u8befu7684u662fu7528u4e0du4e86u7684u3002u4e0bu8f7du5730u5740uff1axa0',\r\n u' \r\n '],\r\n 'link': [u'https://pypi.python.org/pypi/lxml/3.2.3'],\r\n 'title': [u'https://pypi.python.org/pypi/lxml/3.2.3']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u8981u5b89u88c5scrapyuff0cu8fd0u884cu4ee5u4e0bu547du4ee4uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n ', u'\r\n', u'\r\n '], 'link': [], 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u5b89u88c5', u' \r\n '],\r\n 'link': [u'http://brew.sh/'],\r\n 'title': [u'homebrew']}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u8bbeu7f6eu73afu5883u53d8u91cf PATH u6307u5b9axa0homebrewxa0u5305u5728u7cfbu7edfu8f6fu4ef6u5305u524du4f7fu7528uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u53d8u66f4u5b8cu6210u540euff0cu91cdu65b0u52a0u8f7d .bashrc u4f7fu7528u4e0bu9762u7684u547du4ee4uff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u63a5u4e0bu6765uff0cu4f7fu7528u4e0bu9762u7684u547du4ee4u5b89u88c5xa0Pythonuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] DEBUG: Scraped from \u0026lt;200 http://www.yiibai.com/scrapy/scrapy_environment.html\u0026gt;\r\n{'desc': [u'\r\n u63a5u4e0bu6765uff0cu5b89u88c5scrapyuff1a\r\n',\r\n u'\r\n '],\r\n 'link': [],\r\n 'title': []}\r\n2016-10-03 13:11:06 [scrapy] INFO: Closing spider (finished)\r\n2016-10-03 13:11:06 [scrapy] INFO: Dumping Scrapy stats:\r\n{'downloader/request_bytes': 709,\r\n 'downloader/request_count': 3,\r\n 'downloader/request_method_count/GET': 3,\r\n 'downloader/response_bytes': 15401,\r\n 'downloader/response_count': 3,\r\n 'downloader/response_status_count/200': 3,\r\n 'finish_reason': 'finished',\r\n 'finish_time': datetime.datetime(2016, 10, 3, 5, 11, 6, 478000),\r\n 'item_scraped_count': 210,\r\n 'log_count/DEBUG': 214,\r\n 'log_count/INFO': 7,\r\n 'response_received_count': 3,\r\n 'scheduler/dequeued': 2,\r\n 'scheduler/dequeued/memory': 2,\r\n 'scheduler/enqueued': 2,\r\n 'scheduler/enqueued/memory': 2,\r\n 'start_time': datetime.datetime(2016, 10, 3, 5, 11, 5, 197000)}\r\n2016-10-03 13:11:06 [scrapy] INFO: Spider closed (finished)\r\n\r\nD:first_scrapy\u0026gt;\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"35:T12b5,"])</script><script>self.__next_f.push([1,"\u003cp\u003e日誌記錄是指使用內置的日誌系統和定義的函數或類來實現應用程序和庫的事件跟蹤。 記錄日誌是一個即用型的程序庫,它可以在Scrapy設置日誌記錄中的設置列表工作。 Scrapy將運行命令時使用 \u003cem\u003escrapy.utils.log.configure_logging()\u003c/em\u003e 設置一些默認設置和如何處理這些設置。\u003c/p\u003e \n\u003ch2\u003e日誌級別 - Log levels\u003c/h2\u003e \n\u003cp\u003e在Python中日誌消息有五種不同級別的嚴重程度。下面的列表以升序顯示標準的日誌消息:\u003c/p\u003e \n\u003cul\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.DEBUG\u003c/code\u003e - 用於調試信息(最低嚴重性)\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.INFO\u003c/code\u003e - 用於信息消息\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.WARNING\u003c/code\u003e - 用於警告消息\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.ERROR\u003c/code\u003e- 用於正則錯誤\u003c/p\u003e \u003c/li\u003e \n \u003cli\u003e\u003cp\u003e\u003ccode\u003elogging.CRITICAL\u003c/code\u003e - 用於嚴重錯誤(最高嚴重性)\u003c/p\u003e \u003c/li\u003e \n\u003c/ul\u003e \n\u003ch2\u003e如何記錄消息\u003c/h2\u003e \n\u003cp\u003e下面給出簡單的代碼顯示日誌記錄是使用 logging.info 級別的消息。\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogging.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e以上日誌信息可以通過使用 logging.log 參數傳遞,如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogging.log(logging.INFO, \"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e現在,也可以使用 loggers 來關閉消息,通過記錄日誌助手來獲取日誌消息,如下圖所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger()\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e可以有多個記錄器,可以通過 logging.getLogger()函數使用名字進行訪問,如下圖所示。\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger('mycustomlogger')\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e自定義記錄器可以通過使用模塊路徑 \u003cstrong\u003ename\u003c/strong\u003e 變量用於其它任何模塊中,如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nlogger = logging.getLogger(__name__)\r\nlogger.info(\"This is an information\")\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003eSpider的日誌記錄\u003c/h2\u003e \n\u003cp\u003e每個 spider 實例都有一個內置記錄器,並可調用如下:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport scrapy\r\nclass LogSpider(scrapy.Spider):\r\n\r\n name = 'logspider'\r\n start_urls = ['http://dmoz.com']\r\n\r\n def parse(self, response):\r\n self.logger.info('Parse function called on %s', response.url)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e在上面的代碼中,logger是使用蜘蛛的名字創建的,但您可以使用Python提供的自定義 logger,如下面的代碼:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nimport scrapy\r\n\r\nlogger = logging.getLogger('customizedlogger')\r\nclass LogSpider(scrapy.Spider):\r\n\r\n name = 'logspider'\r\n start_urls = ['http://dmoz.com']\r\n\r\n def parse(self, response):\r\n logger.info('Parse function called on %s', response.url)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e日誌記錄配置\u003c/h2\u003e \n\u003cp\u003e記錄器不能夠顯示由自己發出消息。因此,它們需要「處理程序」顯示這些消息,以及處理程序將它們被重定向這些消息到各自的目的地,如文件,電子郵件,標準輸出。\u003c/p\u003e \n\u003cp\u003e根據下面的設置,Scrapy 將配置 \u003cem\u003elogger\u003c/em\u003e 的處理程序。\u003c/p\u003e \n\u003ch2\u003e日誌消息設置\u003c/h2\u003e \n\u003cp\u003e下面給出的設置用於配置日誌記錄:\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_FILE\u003c/em\u003e 和 \u003cem\u003eLOG_ENABLED\u003c/em\u003e 決定日誌消息目的地。\u003c/p\u003e \n\u003cp\u003e當您設置了 \u003cem\u003eLOG_ENCODING\u003c/em\u003e ,它不會顯示日誌輸出消息。\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_LEVEL\u003c/em\u003e 設置確定消息的嚴重性順序;嚴重程度不高的消息將被過濾掉。\u003c/p\u003e \n\u003cp\u003e\u003cem\u003eLOG_FORMAT\u003c/em\u003e 和 \u003cem\u003eLOG_DATEFORMAT\u003c/em\u003e 用於指定所有消息的佈局。\u003c/p\u003e \n\u003cp\u003e當您設置 LOG_STDOUT 爲 true ,所有的進程的標準輸出和錯誤消息將被重定向到日誌中。\u003c/p\u003e \n\u003ch2\u003e命令行選項\u003c/h2\u003e \n\u003cp\u003eScrapy設置可以通過命令行參數來覆蓋,如下面的表:\u003c/p\u003e \n\u003ctable\u003e \n \u003cthead\u003e \n \u003ctr\u003e \n \u003cth\u003eS.N.\u003c/th\u003e \n \u003cth\u003e命令\u003c/th\u003e \n \u003cth\u003e描述\u003c/th\u003e \n \u003c/tr\u003e \n \u003c/thead\u003e \n \u003ctbody\u003e \n \u003ctr\u003e \n \u003ctd\u003e 1\u003c/td\u003e \n \u003ctd\u003e—logfile FILE\u003c/td\u003e \n \u003ctd\u003e覆蓋 LOG_FILE\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 2\u003c/td\u003e \n \u003ctd\u003e—loglevel/-L LEVEL\u003c/td\u003e \n \u003ctd\u003e覆蓋 LOG_LEVEL\u003c/td\u003e \n \u003c/tr\u003e \n \u003ctr\u003e \n \u003ctd\u003e 3\u003c/td\u003e \n \u003ctd\u003e—nolog\u003c/td\u003e \n \u003ctd\u003e設置 LOG_ENABLED 爲 false\u003c/td\u003e \n \u003c/tr\u003e \n \u003c/tbody\u003e \n\u003c/table\u003e \n\u003cp\u003e要手動配置日誌輸出,可以使用 logging.basicConfig(),如下所示:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003eimport logging\r\nfrom scrapy.utils.log import configure_logging\r\n\r\nconfigure_logging(install_root_handler=False)\r\nlogging.basicConfig(\r\n filename='logging.txt',\r\n format='%(levelname)s: %(your_message)s',\r\n level=logging.INFO\r\n)\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e參考 - \u003ca href=\"https://doc.scrapy.org/en/0.24/topics/logging.html\"\u003ehttps://doc.scrapy.org/en/0.24/topics/logging.html\u003c/a\u003e\u003c/p\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"36:T121b,"])</script><script>self.__next_f.push([1,"\u003ch2\u003eScrapy快速入門\u003c/h2\u003e \n\u003cp\u003e最好的學習方法是參考例子,Scrapy 也不例外。出於這個原因,有一個 Scrapy 項目名爲 quotesbot 例子,可以參考它瞭解和使用 Scrapy。它包含兩個蜘蛛用於抓取 \u003ca href=\"http://quotes.toscrape.com\"\u003ehttp://quotes.toscrape.com\u003c/a\u003e, 一個使用CSS選擇器,而另一個使用XPath表達式。\u003c/p\u003e \n\u003cblockquote\u003e \n \u003cp\u003e提示:安裝 Scrapy 開發環境配置請參考 - http://www.yiibai.com/scrapy/scrapy_environment.html\u003c/p\u003e \n\u003c/blockquote\u003e \n\u003cp\u003e項目 quotesbot 的源代碼可在: \u003ca href=\"https://github.com/scrapy/quotesbot\" title=\"https://github.com/scrapy/quotesbot\"\u003ehttps://github.com/scrapy/quotesbot\u003c/a\u003e. 在這裏可以找到關於項目 README 更多信息。\u003c/p\u003e \n\u003cp\u003e如果你熟悉使用 Git,可以檢出的代碼。否則點擊\u003ca href=\"https://github.com/scrapy/quotesbot/archive/master.zip\" title=\"這裏下載\"\u003e這裏下載\u003c/a\u003e該項目源代碼的 zip 文件。\u003cbr\u003e現在我們一步步的瞭解和學習這個項目。\u003c/p\u003e \n\u003ch2\u003equotesbot 項目簡介\u003c/h2\u003e \n\u003cp\u003e這是一個 \u003ccode\u003eScrapy\u003c/code\u003e 示例(入門)的項目,它實現從 \u003ca href=\"http://quotes.toscrape.com\" title=\"http://quotes.toscrape.com\"\u003ehttp://quotes.toscrape.com\u003c/a\u003e 上爬行抓取名人名言。\u003c/p\u003e \n\u003cp\u003e這個項目只是針對學習演示目的。\u003c/p\u003e \n\u003ch3\u003e提取數據\u003c/h3\u003e \n\u003cp\u003e這個項目將提取名言,以及各自的作者姓名和標籤相結合。提取的數據看起來是這樣的,如下例子:\u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-json\"\u003e{\r\n 'author': 'Douglas Adams',\r\n 'text': '「I may not have gone where I intended to go, but I think I ...」',\r\n 'tags': ['life', 'navigation']\r\n}\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e蜘蛛 - Spiders\u003c/h2\u003e \n\u003cp\u003e該項目包含兩個蜘蛛(\u003ccode\u003eSpider\u003c/code\u003e),可以使用 \u003ccode\u003elist\u003c/code\u003e 命令列出它們:\u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-shell\"\u003e$ scrapy list\r\ntoscrape-css\r\ntoscrape-xpath\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e這兩種蜘蛛提取同一網站相同的數據,但是如果要刮取 \u003ccode\u003eCSS\u003c/code\u003e,則使用 \u003ccode\u003eCSS\u003c/code\u003e 選擇器,而要刮取 \u003ccode\u003eXPath\u003c/code\u003e 則採用 \u003ccode\u003eXPath\u003c/code\u003e 表達式。\u003c/p\u003e \n\u003cp\u003e您可以通過Scrapy教程去了解更多的蜘蛛。\u003c/p\u003e \n\u003ch2\u003e運行蜘蛛\u003c/h2\u003e \n\u003cp\u003e您可以使用 \u003ccode\u003escrapy\u003c/code\u003e 爬行的命令,如運行一個蜘蛛:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e$ scrapy crawl toscrape-css\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e如果想保存數據刮到一個文件,可以通過 \u003ccode\u003e-o\u003c/code\u003e 選項:\u003c/p\u003e \n\u003cpre\u003e\u003ccode\u003e$ scrapy crawl toscrape-css -o quotes.json\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e代碼實現\u003c/h2\u003e \n\u003cp\u003e我們先來看看 \u003ccode\u003equotesbot/spiders/toscrape-xpath.py\u003c/code\u003e 的代碼實現 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-python\"\u003e# -*- coding: utf-8 -*-\r\nimport scrapy\r\n\r\n\r\nclass ToScrapeSpiderXPath(scrapy.Spider):\r\n name = 'toscrape-xpath'\r\n start_urls = [\r\n 'http://quotes.toscrape.com/',\r\n ]\r\n\r\n def parse(self, response):\r\n for quote in response.xpath('//div[@class=\"quote\"]'):\r\n yield {\r\n 'text': quote.xpath('./span[@class=\"text\"]/text()').extract_first(),\r\n 'author': quote.xpath('.//small[@class=\"author\"]/text()').extract_first(),\r\n 'tags': quote.xpath('.//div[@class=\"tags\"]/a[@class=\"tag\"]/text()').extract()\r\n }\r\n\r\n next_page_url = response.xpath('//li[@class=\"next\"]/a/@href').extract_first()\r\n if next_page_url is not None:\r\n yield scrapy.Request(response.urljoin(next_page_url))\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003cp\u003e另外一個 Spider 採用 XPath 表達式 \u003ccode\u003equotesbot/spiders/toscrape-xpath.py\u003c/code\u003e 的代碼實現 - \u003c/p\u003e \n\u003cpre\u003e\u003ccode class=\"lang-python\"\u003e# -*- coding: utf-8 -*-\r\nimport scrapy\r\n\r\n\r\nclass ToScrapeSpiderXPath(scrapy.Spider):\r\n name = 'toscrape-xpath'\r\n start_urls = [\r\n 'http://quotes.toscrape.com/',\r\n ]\r\n\r\n def parse(self, response):\r\n for quote in response.xpath('//div[@class=\"quote\"]'):\r\n yield {\r\n 'text': quote.xpath('./span[@class=\"text\"]/text()').extract_first(),\r\n 'author': quote.xpath('.//small[@class=\"author\"]/text()').extract_first(),\r\n 'tags': quote.xpath('.//div[@class=\"tags\"]/a[@class=\"tag\"]/text()').extract()\r\n }\r\n\r\n next_page_url = response.xpath('//li[@class=\"next\"]/a/@href').extract_first()\r\n if next_page_url is not None:\r\n yield scrapy.Request(response.urljoin(next_page_url))\r\n\u003c/code\u003e\u003c/pre\u003e \n\u003ch2\u003e參考\u003c/h2\u003e \n\u003cul\u003e \n \u003cli\u003e\u003ca href=\"https://doc.scrapy.org/en/1.2/intro/examples.html\" title=\"https://doc.scrapy.org/en/1.2/intro/examples.html\"\u003ehttps://doc.scrapy.org/en/1.2/intro/examples.html\u003c/a\u003e\u003c/li\u003e \n\u003c/ul\u003e \n\u003cbr\u003e"])</script><script>self.__next_f.push([1,"d:[\"$\",\"div\",null,{\"className\":\"page-content\",\"children\":[\"$\",\"div\",null,{\"className\":\"container\",\"children\":[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[[\"$\",\"$L10\",null,{\"tutorial\":{\"state\":\"published\",\"_id\":\"59fda5721e18b40005abb5cd\",\"key\":\"scrapy\",\"indexUrl\":\"index\",\"parent\":\"59fda3d41e18b40005abb52b\",\"description\":\"Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。\",\"url\":\"scrapy\",\"name\":\"Scrapy教學\",\"__v\":0,\"sections\":[{\"order\":0,\"_id\":\"59fda5721e18b40005abb5ce\",\"isDefault\":false,\"name\":\"Scrapy教程\",\"sortedPosts\":[{\"order\":0,\"_id\":\"5fcf8cf0d5dd8e00183d8ac1\",\"post\":{\"meta\":{\"description\":\"Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。\",\"keywords\":\"Scrapy教程\"},\"content\":{\"extended\":\"$11\"},\"state\":\"published\",\"views\":1135,\"order\":0,\"_id\":\"59fda5721e18b40005abb5cf\",\"key\":\"index-141\",\"url\":\"index\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy教學\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:06.587Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.907Z\"}},{\"order\":2,\"_id\":\"5fcf8cf0d5dd8e00183d8ac2\",\"post\":{\"meta\":{\"description\":\"在本章中,我們將瞭解如何安裝和設置Scrapy。Scrapy必須與Python一起安裝。 Scrapy可以通過使用 pip 進行安裝。運行以下命令: pip install Scrapy Windows系統上安裝(本教程) 參考 - http://www.\",\"keywords\":\"Scrapy,安裝,setup\"},\"content\":{\"extended\":\"$12\"},\"state\":\"published\",\"views\":1240,\"order\":2,\"_id\":\"59fda5731e18b40005abb5d0\",\"key\":\"scrapy-environment\",\"url\":\"scrapy-environment\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy安裝\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.106Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.897Z\"}},{\"order\":3,\"_id\":\"5fcf8cf0d5dd8e00183d8ac3\",\"post\":{\"meta\":{\"description\":\"Scrapy命令行工具用於控制Scrapy,它通常被稱爲「Scrapy工具」。它包括用於不同對象的參數和選項組的命令。 配置設置 scrapy會找到scrapy.cfg文件中設置的配置。如下面提到的: C:\\\\scrapy(p\",\"keywords\":\"Scrapy,命令行,工具\"},\"content\":{\"extended\":\"$13\"},\"state\":\"published\",\"views\":586,\"order\":3,\"_id\":\"59fda5731e18b40005abb5d1\",\"key\":\"scrapy-command-line-tools\",\"url\":\"scrapy-command-line-tools\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy命令行工具\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.373Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.882Z\"}},{\"order\":4,\"_id\":\"5fcf8cf0d5dd8e00183d8ac4\",\"post\":{\"meta\":{\"description\":\"Spider是負責定義如何遵循通過網站的鏈接並提取網頁中的信息的類。 Scrapy默認的Spider如下: scrapy.Spider 它是所有其他的蜘蛛(spider)都必須繼承的類。它具有以下類: class scrapy.spider\",\"keywords\":\"Scrapy,蜘蛛,Spider\"},\"content\":{\"extended\":\"$14\"},\"state\":\"published\",\"views\":865,\"order\":4,\"_id\":\"59fda5731e18b40005abb5d2\",\"key\":\"scrapy-spiders\",\"url\":\"scrapy-spiders\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy蜘蛛(Spider)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.714Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.854Z\"}},{\"order\":5,\"_id\":\"5fcf8cf0d5dd8e00183d8ac5\",\"post\":{\"meta\":{\"description\":\"當刮取網頁中的數據,需要通過使用XPath或CSS表達式來實現選擇器機制提取HTML源代碼的某些部分。 選擇器是在Python語言的XML和LXML庫建成的 我們使用下面的代碼片段在本章中來定義選擇\",\"keywords\":\"Scrapy,選擇器,Selector\"},\"content\":{\"extended\":\"$15\"},\"state\":\"published\",\"views\":547,\"order\":5,\"_id\":\"59fda5741e18b40005abb5d3\",\"key\":\"scrapy-selectors\",\"url\":\"scrapy-selectors\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy選擇器(Selector)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.017Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.839Z\"}},{\"order\":6,\"_id\":\"5fcf8cf0d5dd8e00183d8ac6\",\"post\":{\"meta\":{\"description\":\"Scrapy進程可通過使用蜘蛛提取來自網頁中的數據。Scrapy使用Item類生成輸出對象用於收刮數據。 聲明項目 如下圖所示,您可以通過使用字段對象和類定義語法聲明項目: import scrapyclas\",\"keywords\":\"Scrapy,項目,Item\"},\"content\":{\"extended\":\"$16\"},\"state\":\"published\",\"views\":576,\"order\":6,\"_id\":\"59fda5741e18b40005abb5d4\",\"key\":\"scrapy-items\",\"url\":\"scrapy-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy項目(Items)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.321Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.831Z\"}},{\"order\":7,\"_id\":\"5fcf8cf0d5dd8e00183d8ac7\",\"post\":{\"meta\":{\"description\":\"項目加載器提供了一個方便的方式來填補從網站上刮取的項目。 聲明項目加載器 項目加載器的聲明類:Items。例如: from scrapy.loader import ItemLoaderfrom scrapy.loader.processors import TakeFirst, M\",\"keywords\":\"Scrapy,項目,加載器,Loader\"},\"content\":{\"extended\":\"$17\"},\"state\":\"published\",\"views\":501,\"order\":7,\"_id\":\"59fda5741e18b40005abb5d5\",\"key\":\"scrapy-item-loaders\",\"url\":\"scrapy-item-loaders\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy項目加載器(Item Loader)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.625Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.822Z\"}},{\"order\":8,\"_id\":\"5fcf8cf0d5dd8e00183d8ac8\",\"post\":{\"meta\":{\"description\":\"Scrapyshell可用於抓取數據並提示錯誤代碼,而無需使用蜘蛛。Scrapyshell的主要目的是測試所提取的代碼,XPath或CSS表達式。它還用來從中指定刮取數據的網頁。 配置Shell shell可以通過安裝\",\"keywords\":\"Scrapy,Shell\"},\"content\":{\"extended\":\"$18\"},\"state\":\"published\",\"views\":728,\"order\":8,\"_id\":\"59fda5741e18b40005abb5d6\",\"key\":\"scrapy-shell\",\"url\":\"scrapy-shell\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy Shell\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.929Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.804Z\"}},{\"order\":9,\"_id\":\"5fcf8cf0d5dd8e00183d8ac9\",\"post\":{\"meta\":{\"description\":\"從網頁中刮取數據,首先需要創建Scrapy項目,用於編寫存儲代碼。要創建一個新的目錄下,運行下面的命令: scrapy startproject first_scrapy 上面的代碼將創建一個名稱爲 first_scrapy 的一個目\",\"keywords\":\"Scrapy,創建項目\"},\"content\":{\"extended\":\"\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cp\u003e 從網頁中刮取數據,首先需要創建Scrapy項目,用於編寫存儲代碼。要創建一個新的目錄下,運行下面的命令: \u003c/p\u003e \\n\u003cpre\u003e\u003cspan class=\\\"hljs-title\\\"\u003escrapy\u003c/span\u003e startproject first_scrapy\u003c/pre\u003e \\n\u003cp\u003e \u003cimg src=\\\"https://asset.1ju.org/cmsstatic/scrapy-1.jpg\\\" alt=\\\"Scrapy創建項目\\\"\u003e\u003cbr\u003e 上面的代碼將創建一個名稱爲 first_scrapy 的一個目錄,它將包含以下結構: \u003c/p\u003e \\n\u003cpre class=\\\"prettyprint lang-py\\\"\u003efirst_scrapy/\\r\\nscrapy.cfg # deploy configuration file\\r\\nfirst_scrapy/ # project's Python module, you'll import your code from here\\r\\n__init__.py\\r\\nitems.py # project items file\\r\\npipelines.py # project pipelines file\\r\\nsettings.py # project settings file\\r\\nspiders/ # a directory where you'll later put your spiders\\r\\n__init__.py\u003c/pre\u003e \\n\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cdiv\u003e \\n\u003c/div\u003e \\n\u003cbr\u003e\"},\"state\":\"published\",\"views\":470,\"order\":9,\"_id\":\"59fda5751e18b40005abb5d7\",\"key\":\"scrapy-create-project\",\"url\":\"scrapy-create-project\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy創建項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:09.473Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.794Z\"}},{\"order\":10,\"_id\":\"5fcf8cf0d5dd8e00183d8aca\",\"post\":{\"meta\":{\"description\":\"項目是用於收集從網站刮取下數據的容器。 在啓動蜘蛛時必須要定義項目。 要定義項目,在目錄 first_scrapy(自定義目錄)下找到文件編輯 items.py . items.py 看起來如下所示: import scrapy\",\"keywords\":\"Scrapy,定義項目\"},\"content\":{\"extended\":\"\u003cp\u003e項目是用於收集從網站刮取下數據的容器。 在啓動蜘蛛時必須要定義項目。 要定義項目,在目錄 first_scrapy自定義目錄下找到編輯items.py文件。items.py 看起來如下所示:\u003c/p\u003e \\n\u003cpre\u003e\u003ccode\u003eimport scrapy\\r\\n\\r\\nclass First_scrapyItem(scrapy.Item):\\r\\n # define the fields for your item here like:\\r\\n # name = scrapy.Field()\\r\\n\u003c/code\u003e\u003c/pre\u003e \\n\u003cp\u003eMyItem 類包含一個數字,scrapy已爲我們建成預先定義的對象繼承項目。舉例來說,如果想從網站中提取名稱,URL和說明, 需要定義字段這三個屬性。\u003cbr\u003e因此,讓我們再補充一點,來收集這些項目:\u003c/p\u003e \\n\u003cpre\u003e\u003ccode\u003efrom scrapy.item import Item, Field\\r\\n\\r\\nclass First_scrapyItem(scrapy.Item):\\r\\n name = scrapy.Field()\\r\\n url = scrapy.Field()\\r\\n desc = scrapy.Field()\\r\\n\u003c/code\u003e\u003c/pre\u003e \\n\u003cbr\u003e\"},\"state\":\"published\",\"views\":452,\"order\":10,\"_id\":\"59fda5751e18b40005abb5d8\",\"key\":\"scrapy-define-item\",\"url\":\"scrapy-define-item\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy定義項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:09.736Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.791Z\"}},{\"order\":11,\"_id\":\"5fcf8cf0d5dd8e00183d8acb\",\"post\":{\"meta\":{\"description\":\"Spider定義從提取數據的初始 *URL*,如何遵循分頁鏈接以及如何提取和分析在 *items.py* 定義字段的類。*Scrapy* 提供了不同類型的蜘蛛,每個都給出了一個具體的目的。\",\"keywords\":\"Scrapy,Spider,蜘蛛\"},\"content\":{\"extended\":\"$19\"},\"state\":\"published\",\"views\":627,\"order\":11,\"_id\":\"59fda5761e18b40005abb5d9\",\"key\":\"scrapy-first-spider\",\"url\":\"scrapy-first-spider\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy第一個Spider\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.040Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.787Z\"}},{\"order\":12,\"_id\":\"5fcf8cf0d5dd8e00183d8acc\",\"post\":{\"meta\":{\"description\":\"要執行蜘蛛抓取數據,在 *first_scrapy* 目錄中運行以下命令: \\r\\n```\\r\\nscrapy crawl first\\r\\n```\\r\\n在這裏,*first* 是創建蜘蛛時指定的蜘蛛名稱。\\r\\n\\r\\n當蜘蛛開始抓取後,可以看到如下面的輸出:\",\"keywords\":\"Scrapy,執行,爬行,捉取\"},\"content\":{\"extended\":\"$1a\"},\"state\":\"published\",\"views\":479,\"order\":12,\"_id\":\"59fda5761e18b40005abb5da\",\"key\":\"scrapy-crawling\",\"url\":\"scrapy-crawling\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy執行爬行捉取\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.594Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.783Z\"}},{\"order\":13,\"_id\":\"5fcf8cf0d5dd8e00183d8acd\",\"post\":{\"meta\":{\"description\":\"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些\",\"keywords\":\"Scrapy,提取,項目\"},\"content\":{\"extended\":\"$1b\"},\"state\":\"published\",\"views\":501,\"order\":13,\"_id\":\"59fda5761e18b40005abb5db\",\"key\":\"scrapy-extracting-items\",\"url\":\"scrapy-extracting-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy提取項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.857Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.778Z\"}},{\"order\":14,\"_id\":\"5fcf8cf0d5dd8e00183d8ace\",\"post\":{\"meta\":{\"description\":\"項目(Item)對象是Python中的常規的字典類型。我們可以用下面的語法來訪問類的屬性:\",\"keywords\":\"Scrapy,使用項目\"},\"content\":{\"extended\":\"$1c\"},\"state\":\"published\",\"views\":481,\"order\":14,\"_id\":\"59fda5771e18b40005abb5dc\",\"key\":\"scrapy-using-item\",\"url\":\"scrapy-using-item\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy使用項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.161Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.771Z\"}},{\"order\":15,\"_id\":\"5fcf8cf0d5dd8e00183d8acf\",\"post\":{\"meta\":{\"description\":\"日誌記錄是指使用內置的日誌系統和定義的函數或類來實現應用程序和庫的事件跟蹤。 記錄日誌是一個即用型的程序庫,它可以在Scrapy設置日誌記錄中的設置列表工作。 Scrapy將運行命令時使\",\"keywords\":\"Scrapy,日誌,logger\"},\"content\":{\"extended\":\"$1d\"},\"state\":\"published\",\"views\":677,\"order\":15,\"_id\":\"59fda5771e18b40005abb5dd\",\"key\":\"scrapy-logging\",\"url\":\"scrapy-logging\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy日誌\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.465Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.764Z\"}},{\"order\":16,\"_id\":\"5fcf8cf0d5dd8e00183d8ad0\",\"post\":{\"meta\":{\"description\":\"最好的學習方法是參考例子,Scrapy 也不例外。出於這個原因,有一個 Scrapy 項目名爲 quotesbot 例子,可以參考它瞭解和使用 Scrapy。它包含兩個蜘蛛用於抓取 http://quotes.toscrape.com, 一個使用CSS選擇\",\"keywords\":\"Scrapy,快速,入門\"},\"content\":{\"extended\":\"$1e\"},\"state\":\"published\",\"views\":550,\"order\":16,\"_id\":\"59fda5771e18b40005abb5de\",\"key\":\"quick-start-2\",\"url\":\"quick-start\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy快速入門\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.768Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.740Z\"}}]}]},\"post\":{\"meta\":{\"description\":\"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些\",\"keywords\":\"Scrapy,提取,項目\"},\"content\":{\"extended\":\"$1f\",\"markdown\":\"$20\",\"html\":\"$21\"},\"state\":\"published\",\"views\":501,\"order\":13,\"_id\":\"59fda5761e18b40005abb5db\",\"key\":\"scrapy-extracting-items\",\"url\":\"scrapy-extracting-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy提取項目\",\"author\":{\"isPublic\":true,\"isOrganiser\":false,\"isAdmin\":true,\"isVerified\":false,\"isOpen\":false,\"_id\":\"59fa8cb8a31fb7001009c4bb\",\"email\":\"inkebook@outlook.com\",\"password\":\"$$2a$10$94Vw.V1wl1cC4R5SnV54ZOrUfeS0F42MdiV4fkJtjonMaKVuaxBe.\",\"isProtected\":false,\"__v\":0,\"photo\":{\"exists\":false,\"folder\":null},\"url\":\"/member/undefined\",\"_\":{\"name\":{},\"email\":{},\"password\":{},\"resetPasswordKey\":{},\"isPublic\":{},\"isOrganiser\":{},\"photo\":{},\"github\":{},\"twitter\":{},\"website\":{},\"bio\":{},\"gravatar\":{},\"isAdmin\":{},\"isVerified\":{},\"isOpen\":{},\"createdAt\":{},\"createdBy\":{},\"updatedAt\":{},\"updatedBy\":{}},\"id\":\"59fa8cb8a31fb7001009c4bb\"},\"publishedDate\":\"2017-11-04T11:33:10.857Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.778Z\",\"updatedAtPretty\":\"2020年10月13日\",\"_\":{\"title\":{},\"state\":{},\"author\":{},\"publishedDate\":{},\"meta\":{\"keywords\":{},\"description\":{}},\"content\":{\"markdown\":{}},\"categories\":{},\"views\":{},\"ratingCount\":{},\"ratingAvg\":{},\"section\":{},\"tutorial\":{},\"url\":{},\"order\":{},\"createdAt\":{},\"createdBy\":{},\"updatedAt\":{},\"updatedBy\":{}},\"id\":\"59fda5761e18b40005abb5db\"}}],[\"$\",\"div\",null,{\"className\":\"col-12 col-sm-8\",\"children\":[[\"$\",\"$L22\",null,{}],[\"$\",\"div\",null,{\"className\":\"book card\",\"children\":[[\"$\",\"div\",null,{\"className\":\"card-header\",\"children\":[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[[\"$\",\"div\",null,{\"className\":\"col\",\"children\":[[\"$\",\"svg\",null,{\"aria-hidden\":\"true\",\"focusable\":\"false\",\"data-prefix\":\"fas\",\"data-icon\":\"arrow-left\",\"className\":\"svg-inline--fa fa-arrow-left \",\"role\":\"img\",\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 448 512\",\"style\":{},\"children\":[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\",\"style\":{}}]}],[\"$\",\"$Lf\",null,{\"href\":\"/scrapy/scrapy-crawling\",\"children\":\"Scrapy執行爬行捉取\"}]]}],[\"$\",\"div\",null,{\"className\":\"col text-md-end\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/scrapy/scrapy-using-item\",\"children\":[[\"$\",\"svg\",null,{\"aria-hidden\":\"true\",\"focusable\":\"false\",\"data-prefix\":\"fas\",\"data-icon\":\"arrow-right\",\"className\":\"svg-inline--fa fa-arrow-right \",\"role\":\"img\",\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 448 512\",\"style\":{},\"children\":[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z\",\"style\":{}}]}],\"Scrapy使用項目\"]}]}]]}]}],[\"$\",\"div\",null,{\"className\":\"card-body p-lg-30\",\"children\":[[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"div\",null,{\"className\":\"col-12 col-lg-9 col-sm-8\",\"children\":[[\"$\",\"h1\",null,{\"className\":\"h2 title\",\"children\":\"Scrapy提取項目\"}],[\"$\",\"div\",null,{\"className\":\"blog-post__byline mb-3\",\"children\":[\"$\",\"div\",null,{\"className\":\"d-sm-inline-block\",\"children\":[[\"$\",\"span\",null,{\"className\":\"split-dot\"}],[\"$\",\"span\",null,{\"className\":\"text-secondary\",\"children\":[\"瀏覽人數:\",[\"$\",\"span\",null,{\"children\":\"501\"}]]}],[\"$\",\"span\",null,{\"className\":\"split-dot\"}],[\"$\",\"span\",null,{\"className\":\"text-secondary\",\"children\":\"最近更新:\"}],[\"$\",\"time\",null,{\"className\":\"text-secondary\",\"dateTime\":\"2020-10-13T08:26:43.778Z\",\"children\":[\"最近更新:\",\"2020年10月13日\"]}]]}]}],\"$undefined\"]}]}],[\"$\",\"article\",null,{\"className\":\"full-post fmt\",\"children\":[[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[\"$\",\"div\",null,{\"className\":\"col\",\"children\":[\"$\",\"$L23\",null,{\"content\":\"$24\"}]}]}],[\"$\",\"div\",null,{\"className\":\"functional-area-bottom\",\"children\":[\"$\",\"div\",null,{\"className\":\"text-center\",\"children\":[\"$\",\"$L25\",null,{\"post\":{\"meta\":{\"description\":\"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些\",\"keywords\":\"Scrapy,提取,項目\"},\"content\":{\"extended\":\"$26\",\"markdown\":\"$27\",\"html\":\"$28\"},\"state\":\"published\",\"views\":501,\"order\":13,\"_id\":\"59fda5761e18b40005abb5db\",\"key\":\"scrapy-extracting-items\",\"url\":\"scrapy-extracting-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy提取項目\",\"author\":{\"isPublic\":true,\"isOrganiser\":false,\"isAdmin\":true,\"isVerified\":false,\"isOpen\":false,\"_id\":\"59fa8cb8a31fb7001009c4bb\",\"email\":\"inkebook@outlook.com\",\"password\":\"$$2a$10$94Vw.V1wl1cC4R5SnV54ZOrUfeS0F42MdiV4fkJtjonMaKVuaxBe.\",\"isProtected\":false,\"__v\":0,\"photo\":{\"exists\":false,\"folder\":null},\"url\":\"/member/undefined\",\"_\":{\"name\":{},\"email\":{},\"password\":{},\"resetPasswordKey\":{},\"isPublic\":{},\"isOrganiser\":{},\"photo\":{},\"github\":{},\"twitter\":{},\"website\":{},\"bio\":{},\"gravatar\":{},\"isAdmin\":{},\"isVerified\":{},\"isOpen\":{},\"createdAt\":{},\"createdBy\":{},\"updatedAt\":{},\"updatedBy\":{}},\"id\":\"59fa8cb8a31fb7001009c4bb\"},\"publishedDate\":\"2017-11-04T11:33:10.857Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.778Z\",\"updatedAtPretty\":\"2020年10月13日\",\"_\":{\"title\":{},\"state\":{},\"author\":{},\"publishedDate\":{},\"meta\":{\"keywords\":{},\"description\":{}},\"content\":{\"markdown\":{}},\"categories\":{},\"views\":{},\"ratingCount\":{},\"ratingAvg\":{},\"section\":{},\"tutorial\":{},\"url\":{},\"order\":{},\"createdAt\":{},\"createdBy\":{},\"updatedAt\":{},\"updatedBy\":{}},\"id\":\"59fda5761e18b40005abb5db\"},\"tutorial\":{\"state\":\"published\",\"_id\":\"59fda5721e18b40005abb5cd\",\"key\":\"scrapy\",\"indexUrl\":\"index\",\"parent\":\"59fda3d41e18b40005abb52b\",\"description\":\"Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。\",\"url\":\"scrapy\",\"name\":\"Scrapy教學\",\"__v\":0,\"sections\":[{\"order\":0,\"_id\":\"59fda5721e18b40005abb5ce\",\"isDefault\":false,\"name\":\"Scrapy教程\",\"sortedPosts\":[{\"order\":0,\"_id\":\"5fcf8cf0d5dd8e00183d8ac1\",\"post\":{\"meta\":{\"description\":\"Scrapy是使用Python編寫的一個快速開源Web抓取框架,使用基於XPath選擇器來提取網頁中的數據。\",\"keywords\":\"Scrapy教程\"},\"content\":{\"extended\":\"$29\"},\"state\":\"published\",\"views\":1135,\"order\":0,\"_id\":\"59fda5721e18b40005abb5cf\",\"key\":\"index-141\",\"url\":\"index\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy教學\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:06.587Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.907Z\"}},{\"order\":2,\"_id\":\"5fcf8cf0d5dd8e00183d8ac2\",\"post\":{\"meta\":{\"description\":\"在本章中,我們將瞭解如何安裝和設置Scrapy。Scrapy必須與Python一起安裝。 Scrapy可以通過使用 pip 進行安裝。運行以下命令: pip install Scrapy Windows系統上安裝(本教程) 參考 - http://www.\",\"keywords\":\"Scrapy,安裝,setup\"},\"content\":{\"extended\":\"$2a\"},\"state\":\"published\",\"views\":1240,\"order\":2,\"_id\":\"59fda5731e18b40005abb5d0\",\"key\":\"scrapy-environment\",\"url\":\"scrapy-environment\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy安裝\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.106Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.897Z\"}},{\"order\":3,\"_id\":\"5fcf8cf0d5dd8e00183d8ac3\",\"post\":{\"meta\":{\"description\":\"Scrapy命令行工具用於控制Scrapy,它通常被稱爲「Scrapy工具」。它包括用於不同對象的參數和選項組的命令。 配置設置 scrapy會找到scrapy.cfg文件中設置的配置。如下面提到的: C:\\\\scrapy(p\",\"keywords\":\"Scrapy,命令行,工具\"},\"content\":{\"extended\":\"$2b\"},\"state\":\"published\",\"views\":586,\"order\":3,\"_id\":\"59fda5731e18b40005abb5d1\",\"key\":\"scrapy-command-line-tools\",\"url\":\"scrapy-command-line-tools\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy命令行工具\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.373Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.882Z\"}},{\"order\":4,\"_id\":\"5fcf8cf0d5dd8e00183d8ac4\",\"post\":{\"meta\":{\"description\":\"Spider是負責定義如何遵循通過網站的鏈接並提取網頁中的信息的類。 Scrapy默認的Spider如下: scrapy.Spider 它是所有其他的蜘蛛(spider)都必須繼承的類。它具有以下類: class scrapy.spider\",\"keywords\":\"Scrapy,蜘蛛,Spider\"},\"content\":{\"extended\":\"$2c\"},\"state\":\"published\",\"views\":865,\"order\":4,\"_id\":\"59fda5731e18b40005abb5d2\",\"key\":\"scrapy-spiders\",\"url\":\"scrapy-spiders\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy蜘蛛(Spider)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:07.714Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.854Z\"}},{\"order\":5,\"_id\":\"5fcf8cf0d5dd8e00183d8ac5\",\"post\":{\"meta\":{\"description\":\"當刮取網頁中的數據,需要通過使用XPath或CSS表達式來實現選擇器機制提取HTML源代碼的某些部分。 選擇器是在Python語言的XML和LXML庫建成的 我們使用下面的代碼片段在本章中來定義選擇\",\"keywords\":\"Scrapy,選擇器,Selector\"},\"content\":{\"extended\":\"$2d\"},\"state\":\"published\",\"views\":547,\"order\":5,\"_id\":\"59fda5741e18b40005abb5d3\",\"key\":\"scrapy-selectors\",\"url\":\"scrapy-selectors\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy選擇器(Selector)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.017Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.839Z\"}},{\"order\":6,\"_id\":\"5fcf8cf0d5dd8e00183d8ac6\",\"post\":{\"meta\":{\"description\":\"Scrapy進程可通過使用蜘蛛提取來自網頁中的數據。Scrapy使用Item類生成輸出對象用於收刮數據。 聲明項目 如下圖所示,您可以通過使用字段對象和類定義語法聲明項目: import scrapyclas\",\"keywords\":\"Scrapy,項目,Item\"},\"content\":{\"extended\":\"$2e\"},\"state\":\"published\",\"views\":576,\"order\":6,\"_id\":\"59fda5741e18b40005abb5d4\",\"key\":\"scrapy-items\",\"url\":\"scrapy-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy項目(Items)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.321Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.831Z\"}},{\"order\":7,\"_id\":\"5fcf8cf0d5dd8e00183d8ac7\",\"post\":{\"meta\":{\"description\":\"項目加載器提供了一個方便的方式來填補從網站上刮取的項目。 聲明項目加載器 項目加載器的聲明類:Items。例如: from scrapy.loader import ItemLoaderfrom scrapy.loader.processors import TakeFirst, M\",\"keywords\":\"Scrapy,項目,加載器,Loader\"},\"content\":{\"extended\":\"$2f\"},\"state\":\"published\",\"views\":501,\"order\":7,\"_id\":\"59fda5741e18b40005abb5d5\",\"key\":\"scrapy-item-loaders\",\"url\":\"scrapy-item-loaders\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy項目加載器(Item Loader)\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.625Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.822Z\"}},{\"order\":8,\"_id\":\"5fcf8cf0d5dd8e00183d8ac8\",\"post\":{\"meta\":{\"description\":\"Scrapyshell可用於抓取數據並提示錯誤代碼,而無需使用蜘蛛。Scrapyshell的主要目的是測試所提取的代碼,XPath或CSS表達式。它還用來從中指定刮取數據的網頁。 配置Shell shell可以通過安裝\",\"keywords\":\"Scrapy,Shell\"},\"content\":{\"extended\":\"$30\"},\"state\":\"published\",\"views\":728,\"order\":8,\"_id\":\"59fda5741e18b40005abb5d6\",\"key\":\"scrapy-shell\",\"url\":\"scrapy-shell\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy Shell\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:08.929Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.804Z\"}},{\"order\":9,\"_id\":\"5fcf8cf0d5dd8e00183d8ac9\",\"post\":{\"meta\":{\"description\":\"從網頁中刮取數據,首先需要創建Scrapy項目,用於編寫存儲代碼。要創建一個新的目錄下,運行下面的命令: scrapy startproject first_scrapy 上面的代碼將創建一個名稱爲 first_scrapy 的一個目\",\"keywords\":\"Scrapy,創建項目\"},\"content\":{\"extended\":\"\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cp\u003e 從網頁中刮取數據,首先需要創建Scrapy項目,用於編寫存儲代碼。要創建一個新的目錄下,運行下面的命令: \u003c/p\u003e \\n\u003cpre\u003e\u003cspan class=\\\"hljs-title\\\"\u003escrapy\u003c/span\u003e startproject first_scrapy\u003c/pre\u003e \\n\u003cp\u003e \u003cimg src=\\\"https://asset.1ju.org/cmsstatic/scrapy-1.jpg\\\" alt=\\\"Scrapy創建項目\\\"\u003e\u003cbr\u003e 上面的代碼將創建一個名稱爲 first_scrapy 的一個目錄,它將包含以下結構: \u003c/p\u003e \\n\u003cpre class=\\\"prettyprint lang-py\\\"\u003efirst_scrapy/\\r\\nscrapy.cfg # deploy configuration file\\r\\nfirst_scrapy/ # project's Python module, you'll import your code from here\\r\\n__init__.py\\r\\nitems.py # project items file\\r\\npipelines.py # project pipelines file\\r\\nsettings.py # project settings file\\r\\nspiders/ # a directory where you'll later put your spiders\\r\\n__init__.py\u003c/pre\u003e \\n\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cp\u003e \u003cbr\u003e \u003c/p\u003e \\n\u003cdiv\u003e \\n\u003c/div\u003e \\n\u003cbr\u003e\"},\"state\":\"published\",\"views\":470,\"order\":9,\"_id\":\"59fda5751e18b40005abb5d7\",\"key\":\"scrapy-create-project\",\"url\":\"scrapy-create-project\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy創建項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:09.473Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.794Z\"}},{\"order\":10,\"_id\":\"5fcf8cf0d5dd8e00183d8aca\",\"post\":{\"meta\":{\"description\":\"項目是用於收集從網站刮取下數據的容器。 在啓動蜘蛛時必須要定義項目。 要定義項目,在目錄 first_scrapy(自定義目錄)下找到文件編輯 items.py . items.py 看起來如下所示: import scrapy\",\"keywords\":\"Scrapy,定義項目\"},\"content\":{\"extended\":\"\u003cp\u003e項目是用於收集從網站刮取下數據的容器。 在啓動蜘蛛時必須要定義項目。 要定義項目,在目錄 first_scrapy自定義目錄下找到編輯items.py文件。items.py 看起來如下所示:\u003c/p\u003e \\n\u003cpre\u003e\u003ccode\u003eimport scrapy\\r\\n\\r\\nclass First_scrapyItem(scrapy.Item):\\r\\n # define the fields for your item here like:\\r\\n # name = scrapy.Field()\\r\\n\u003c/code\u003e\u003c/pre\u003e \\n\u003cp\u003eMyItem 類包含一個數字,scrapy已爲我們建成預先定義的對象繼承項目。舉例來說,如果想從網站中提取名稱,URL和說明, 需要定義字段這三個屬性。\u003cbr\u003e因此,讓我們再補充一點,來收集這些項目:\u003c/p\u003e \\n\u003cpre\u003e\u003ccode\u003efrom scrapy.item import Item, Field\\r\\n\\r\\nclass First_scrapyItem(scrapy.Item):\\r\\n name = scrapy.Field()\\r\\n url = scrapy.Field()\\r\\n desc = scrapy.Field()\\r\\n\u003c/code\u003e\u003c/pre\u003e \\n\u003cbr\u003e\"},\"state\":\"published\",\"views\":452,\"order\":10,\"_id\":\"59fda5751e18b40005abb5d8\",\"key\":\"scrapy-define-item\",\"url\":\"scrapy-define-item\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy定義項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:09.736Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.791Z\"}},{\"order\":11,\"_id\":\"5fcf8cf0d5dd8e00183d8acb\",\"post\":{\"meta\":{\"description\":\"Spider定義從提取數據的初始 *URL*,如何遵循分頁鏈接以及如何提取和分析在 *items.py* 定義字段的類。*Scrapy* 提供了不同類型的蜘蛛,每個都給出了一個具體的目的。\",\"keywords\":\"Scrapy,Spider,蜘蛛\"},\"content\":{\"extended\":\"$31\"},\"state\":\"published\",\"views\":627,\"order\":11,\"_id\":\"59fda5761e18b40005abb5d9\",\"key\":\"scrapy-first-spider\",\"url\":\"scrapy-first-spider\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy第一個Spider\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.040Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.787Z\"}},{\"order\":12,\"_id\":\"5fcf8cf0d5dd8e00183d8acc\",\"post\":{\"meta\":{\"description\":\"要執行蜘蛛抓取數據,在 *first_scrapy* 目錄中運行以下命令: \\r\\n```\\r\\nscrapy crawl first\\r\\n```\\r\\n在這裏,*first* 是創建蜘蛛時指定的蜘蛛名稱。\\r\\n\\r\\n當蜘蛛開始抓取後,可以看到如下面的輸出:\",\"keywords\":\"Scrapy,執行,爬行,捉取\"},\"content\":{\"extended\":\"$32\"},\"state\":\"published\",\"views\":479,\"order\":12,\"_id\":\"59fda5761e18b40005abb5da\",\"key\":\"scrapy-crawling\",\"url\":\"scrapy-crawling\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy執行爬行捉取\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.594Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.783Z\"}},{\"order\":13,\"_id\":\"5fcf8cf0d5dd8e00183d8acd\",\"post\":{\"meta\":{\"description\":\"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些\",\"keywords\":\"Scrapy,提取,項目\"},\"content\":{\"extended\":\"$33\"},\"state\":\"published\",\"views\":501,\"order\":13,\"_id\":\"59fda5761e18b40005abb5db\",\"key\":\"scrapy-extracting-items\",\"url\":\"scrapy-extracting-items\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy提取項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:10.857Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.778Z\"}},{\"order\":14,\"_id\":\"5fcf8cf0d5dd8e00183d8ace\",\"post\":{\"meta\":{\"description\":\"項目(Item)對象是Python中的常規的字典類型。我們可以用下面的語法來訪問類的屬性:\",\"keywords\":\"Scrapy,使用項目\"},\"content\":{\"extended\":\"$34\"},\"state\":\"published\",\"views\":481,\"order\":14,\"_id\":\"59fda5771e18b40005abb5dc\",\"key\":\"scrapy-using-item\",\"url\":\"scrapy-using-item\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy使用項目\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.161Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.771Z\"}},{\"order\":15,\"_id\":\"5fcf8cf0d5dd8e00183d8acf\",\"post\":{\"meta\":{\"description\":\"日誌記錄是指使用內置的日誌系統和定義的函數或類來實現應用程序和庫的事件跟蹤。 記錄日誌是一個即用型的程序庫,它可以在Scrapy設置日誌記錄中的設置列表工作。 Scrapy將運行命令時使\",\"keywords\":\"Scrapy,日誌,logger\"},\"content\":{\"extended\":\"$35\"},\"state\":\"published\",\"views\":677,\"order\":15,\"_id\":\"59fda5771e18b40005abb5dd\",\"key\":\"scrapy-logging\",\"url\":\"scrapy-logging\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy日誌\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.465Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.764Z\"}},{\"order\":16,\"_id\":\"5fcf8cf0d5dd8e00183d8ad0\",\"post\":{\"meta\":{\"description\":\"最好的學習方法是參考例子,Scrapy 也不例外。出於這個原因,有一個 Scrapy 項目名爲 quotesbot 例子,可以參考它瞭解和使用 Scrapy。它包含兩個蜘蛛用於抓取 http://quotes.toscrape.com, 一個使用CSS選擇\",\"keywords\":\"Scrapy,快速,入門\"},\"content\":{\"extended\":\"$36\"},\"state\":\"published\",\"views\":550,\"order\":16,\"_id\":\"59fda5771e18b40005abb5de\",\"key\":\"quick-start-2\",\"url\":\"quick-start\",\"tutorial\":\"59fda5721e18b40005abb5cd\",\"section\":\"59fda5721e18b40005abb5ce\",\"title\":\"Scrapy快速入門\",\"author\":\"59fa8cb8a31fb7001009c4bb\",\"publishedDate\":\"2017-11-04T11:33:11.768Z\",\"__v\":0,\"updatedAt\":\"2020-10-13T08:26:43.740Z\"}}]}]}}]}]}]]}]]}],[\"$\",\"div\",null,{\"className\":\"card-footer\",\"children\":[\"$\",\"div\",null,{\"className\":\"row\",\"children\":[[\"$\",\"div\",null,{\"className\":\"col\",\"children\":[[\"$\",\"svg\",null,{\"aria-hidden\":\"true\",\"focusable\":\"false\",\"data-prefix\":\"fas\",\"data-icon\":\"arrow-left\",\"className\":\"svg-inline--fa fa-arrow-left \",\"role\":\"img\",\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 448 512\",\"style\":{},\"children\":[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\",\"style\":{}}]}],[\"$\",\"$Lf\",null,{\"href\":\"/scrapy/scrapy-crawling\",\"children\":\"Scrapy執行爬行捉取\"}]]}],[\"$\",\"div\",null,{\"className\":\"col text-md-end\",\"children\":[\"$\",\"$Lf\",null,{\"href\":\"/scrapy/scrapy-using-item\",\"children\":[[\"$\",\"svg\",null,{\"aria-hidden\":\"true\",\"focusable\":\"false\",\"data-prefix\":\"fas\",\"data-icon\":\"arrow-right\",\"className\":\"svg-inline--fa fa-arrow-right \",\"role\":\"img\",\"xmlns\":\"http://www.w3.org/2000/svg\",\"viewBox\":\"0 0 448 512\",\"style\":{},\"children\":[\"$\",\"path\",null,{\"fill\":\"currentColor\",\"d\":\"M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z\",\"style\":{}}]}],\"Scrapy使用項目\"]}]}]]}]}]]}]]}]]}]}]}]\n"])</script><script>self.__next_f.push([1,"4:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"1\",{\"children\":\"Scrapy提取項目 - Scrapy教學\"}],[\"$\",\"meta\",\"2\",{\"name\":\"description\",\"content\":\"從網頁中提取數據,Scrapy 使用基於 [XPath](https://www.w3.org/TR/xpath/) 和 [CSS](https://www.w3.org/TR/selectors/) 表達式的技術叫做選擇器。以下是 XPath 表達式的一些\"}],[\"$\",\"meta\",\"3\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script></body></html>