Scrapy——基本用法(命令行工具、Item、Spiders)
命令行工具
創建項目
scrapy startproject myproject該命令經會在myproject目錄中創建一個Scrapy項目。進入到項目根目錄,就可以使用scrapy命令來管理和控制你的項目了。
控制項目
有些Scrapy命令要求在Scrapy項目中運行。另外注意,有些命令在項目里運行時的效果有些區別。
查看所有可用命令
scrapy -hScrapy提供了兩種類型的命令。一種是必須在scrapy項目中運行,另一種則不與需要。
全局命令:
| startproject | scrapy startproject [project_name] | 創建項目 |
| settings | scrapy settings [options] | 在項目中運行時,該命令將會輸出醒目的設定值,否則輸出Scrapy默認設定 |
| runspider | scrapy runspider spider_file.py | 在未創建項目的情況下,運行一個在Python文件中的spider |
| shell | scrapy shell [url] | 以給定的URL或者空啟動Scrapy |
| fetch | scrapy fetch [url] | 使用Scrapy下載器下載給定的URL,并將獲取到的內容送到標準輸出。 |
| view | scrapy view [url] | 在瀏覽器中打開給定的URL,并以Scrapy spider獲取到的形式展現,可以用來檢查spider所獲取到的頁面 |
| version | scrapy version [-v] | 輸出scrapy版本,配合-v運行時,該命令將同時輸出python,Twisted以及平臺的信息,方便bug提交 |
項目命令 |命令|語法|功能| |-|-| |crawl|`scrapy crawl `|使用spider進行爬取| |check|`scrapy check [-l] `|運行contract檢查| |list|scrapy list|列出當前項目種所有可用的spider| |edit|`scrapy edit `|使用EDITOR種設定的編輯器給定的spider| |parse|`scrapy parse [options]`|獲取給定的URL并使用響應的spider分析處理。| |genspider|`scrapy genspider [-t template] `|僅僅是創建spider的一種快捷方法。該方法可以用提前定義好的模板來生成spider,也可以自己創建spider的源碼文件| |deploy|`scrapy deploy [ | -l | -L ]`|將項目部署到Scrapyd服務| |bench|`scrapy bench`|運行benchmark測試|
parse命令參數選項
- –spider=SPIDER:跳過自動檢測spider并強制使用特定的spider;
- –a NAME=VALUE:設置spider的參數
- –callback-cspider中用于解析返回的回調函數
- –pipelines:在pipeline中處理item
- –rules-r:使用CrawlSpider規則來發現用來解析返回的回調函數
- –noitems不顯示爬取道的item
- –nolinks不顯示爬取到的鏈接
- –nocolour避免使用pygments對輸出著色
- –depth-d指定跟進鏈接誒請求的層數默認為1
- –verbose-v顯示每個請求的詳細信息
Items
爬取的主要目的就是從非結構性的數據源提取結構性數據。Scrapy提供Item類來滿足這樣的需求。Item對象是種簡單的容器,保存了爬取到的數據。其提供了類似于字典的API以及用于聲明可用字段的簡單語法。
聲明Item
Item字段
Field對象指明了每個字段的元數據。你可以為每個字段指明任何類型的元數據。設置Field對象的主要目的就是在一個地方定義好所有的元數據。
與Item配合
創建item
獲取字段值
>>> product['name'] Desktop PC >>> product.get('name') Desktop PC>>> product['price'] 1000>>> product['last_updated'] Traceback (most recent call last):... KeyError: 'last_updated'>>> product.get('last_updated', 'not set') not set>>> product['lala'] # getting unknown field Traceback (most recent call last):... KeyError: 'lala'>>> product.get('lala', 'unknown field') 'unknown field'>>> 'name' in product # is name field populated? True>>> 'last_updated' in product # is last_updated populated? False>>> 'last_updated' in product.fields # is last_updated a declared field? True>>> 'lala' in product.fields # is lala a declared field? False設置字段值
>>> product['last_updated'] = 'today' >>> product['last_updated'] today>>> product['lala'] = 'test' # setting unknown field Traceback (most recent call last):... KeyError: 'Product does not support field: lala'獲取所有獲取到的值
print product.keys()# ['price', 'name']print product.items()# [('price', 1000), ('name', 'Desktop PC')]復制item
product2=Product(product)print product2 # {'name': 'Desktop PC', 'price': 1000}product3=product2.copy()print product3 # {'name': 'Desktop PC', 'price': 1000}根據item創建字典
print dict(product)# {'price': 1000, 'name': 'Desktop PC'}根據字典創建item
print Product({'name': 'Laptop PC', 'price': 1500}) # {'name': 'Laptop PC', 'price': 1500}擴展Item
可以通過繼承原始的Item來擴展item
也可以通過使用原字段的元數據,添加新的值或修改原來的值來擴展字段元數據。
class SpecificProduct(Product):name = scrapy.Field(Product.fields['name'], serializer=my_serializer)Item對象
class scrapy.item.Item([arg])返回一個根據給定參數可選初始化的item,Item讀值了標準的dict API。包括初始化函數也相同,為以額外添加的屬性是:field,一個包含了所有聲明的字段的字典,而不僅僅是貨渠道的字段。
Spiders
Spider類定義了如何爬取某個網站,包括了爬取的動作以及如何從網頁的內容中提取結構化數據。還句話說,Spider就是你定義爬取的動作及分析某個網頁的地方。
- 以初始的URL初始化Request,并設置回調函數。當該request下載完畢并返回時,將生成response,并作為參數傳給該回調函數。start_requests()讀取start_urls中的URL,并以parse為回調函數生成Request.
- 在回調函數內分析返回的網頁內容,返回Item對象或者Request或者一個包含二者的可迭代容器。返回的Request對象之后回經過Scrapy處理,下載相應的內容,并調用設置的callback函數。
- 在回調函數內,你可以使用選擇器來分析網頁內容,并根據分析的數據生成item。
- 最后,由spider返回的item將被存到數據庫或使用Feed exports存到文件中。
Spider參數
Spider可以通過接收參數來修改其功能。spider參數一般用來定義初始URL或者指定先值爬取網站的部分。
在運行crawl時添加-a可以傳遞Spider參數:
Spider在構造器中獲取參數。
import scrapyclass MySpider(Spider):name = 'myspider'def __init__(self, category=None, *args, **kwargs):super(MySpider, self).__init__(*args, **kwargs)self.start_urls = ['http://www.example.com/categories/%s' % category]# ...Spider
class scrapy.spider.SpiderSpider是最簡單的spider。每個器它的spider必須繼承自該類。Spider僅僅請求給定的
start_urls/start_requests,并根據返回的結果(resulting/responses)調用spider的parse方法。
- **name:**定義spider名字的字符串。定義了Scrapy如何定位spider,必須是唯一的。不過可以生成多個相同的spider實例。
如果該spider爬取單個網站,一個常見的做法是以該網站來命名spider。 - **allowed_domains:**可選,包含了spider允許爬取的域名列表。當offsiteMiddleware啟用時,域名不在列表中的URL不會被跟進。
- **start_urls:**URL列表,當沒有制定特定的URL時,spider將從該列表中來時進行爬取。因此,第一個被獲取到的頁面的URL將是該列表之一。后續的URL將會從獲取到的數據中提取。
- **start_requests()?*該方法必須返回一個可迭代對象。該對象包含了spider用于爬取的第一個Request。當spider啟動爬取并且未指定URL時,該方法被調用。當指定了URL時,make_requests_from_url()將被調用來創建Request對象。僅近乎uibei調用一次,可視為生成器。該方法默認使用start_urls的url生成Reqest。如果你想修改最初爬取某個網站的Request對象,可以重寫該方法。
- **make_requests_from_url(url)?*該方法接收一個URL并返回用于爬取的Request對象。在初始化時被start_requests()調用,也用于轉化url為request。默認未被復寫的情況下該方法返回的Request對象中,parse()作為回調函數,dont_filter參數也被設置為開啟。
- **parse(respone)?*當response沒有指定回調函數時,該方法時Scapy處理下載的response的默認方法。
parse負責處理respones并返回處理的數據以及跟進的URL。
Spider對其他的Request及Item的可迭代的對象。 - **log(message[,level,component]):*使用scrapy.log.msg()方法記錄message。log中自動帶上該spider的name屬性。
- **closed(reason)?*當spider關閉時,該函數被調用。該方法提供了一個提到調用signals.connect()來監聽spider_closed信號的快捷方式。
樣例
CrawlSpider
class scrapy.contrib.spiders.CrawlSpider爬取一般網站常用的spider。其定義了一些規則來提供跟link的方便機制。除了繼承過來的屬性外,其提供了一個新的屬性。
- **rules:**一個包含一個或多個Rule對象的集合。每個Rule對爬取網站的動作定義了特定的表現。如果rule匹配了相同的鏈接,則根據它們在本屬性中被定義的順序,第一個會被使用。
- **parse_start_url(response)?*當start_url的請求返回時,該方法被調用。該方法分析最初的返回值并必須返回一個 Item 對象或者 一個 Request 對象或者 一個可迭代的包含二者對象。
爬取規則(Crawling rules)
class scrapy.contrib.spiders.Rule(link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=None)- link_extractor是一個Link Extractor對象,其定義了如何從爬取到的頁面提取鏈接。
- callback是一個callable或string。從link_extractor中每獲取到鏈接時將調用該函數。該回調函數接受一個response作為其第一個參數,并返回一個包含Itm以及Request對象的列表。
- cb_kwargs:包含傳遞給回調函數的參數的字典。
- follow是一個布爾值,指定了根據該規則從response提取的鏈接是否需要跟進。如果callback為None,follow默認設置為True,否則默認為False。
- process_link是一個callable或string。主要用來過濾。
- process_reqeust是一個callable或string。該規則提取到每個request時都會調用該函數。該函數必須返回一個request或None.
該spider將從example.com的首頁開始爬取,獲取category以及item的鏈接并對后者使用parse_item方法。當item獲得返回時,將使用XPath處理HTML并生成一些數據填入Item中。
XMLFeedSpider
XMLFeedSpider被設計用于通過迭代各個節點來分析XML源。迭代其可以從iternodes,xml,html選擇。鑒于xml以及html迭代器需要先讀取所有DOM再分析而引起的性能問題,一般還是推薦使用iternodes。
你必須定義下列類屬性來設置迭代器以及標簽名:
**iterator:**用于確定使用哪個迭代器,
- iternodes-一個高性能的基于正則表達式的迭代器;
- html'-使用selector的迭代器。使用DOM進行分析,其需要將所有的DOM載入內存,當數據量大的時候會產生問題。
- xml-和html一樣。
默認值為iternodes。
itertag一個包含開始迭代的節點名的sring。
namespaces一個由(prefix,url)元組所組成的list。其定義了在該文檔中會被spider處理的可用的namespace。prefix及url會被自動調用redister_namespace()生成namespace。可以通過itertag屬性中制定節點的namespace。
**adapt_response(response)**該方法在spider分析response前被調用??梢栽趓esponse被分析前使用該函數來修改內容。
**parse_node(response, selector)**當節點符合提供的標簽名時itertag該方法被調用。接收到的response以及相應的Selector作為參數傳遞給該方法。該方法返回一個Item對象或者Request對象或者一個包含二者的可迭代對象。
**process_results(response, results)**當spider返回結果時該方法被調用。設定該方法的目的是在結果返回給框架核心之前作最后的處理。
CSVFeedSpider
用來爬取CSV文件網頁
該spider除了其按行遍歷而不是節點之外其他和XMLFeedSpider十分類似,而每次迭代時調用的是parse_row().
delimiter在CSV文件中用于區分字段的分隔符。類型為string。默認為’,’;
headers在CSV文件中包含的用來提取字段的行的列表。
**parse_row(response,row)**該方法接收一個response對象及一個以提供或檢測出來的header為鍵的字典。該spider中,你可以覆蓋adapt_response及process_results方法來進行預處理及后處理。
SitemapSpider
class scrapy.contrib.spiders.SitemapSpiderSitemapSpider使你爬取網站時可以通過Sitemaps來發現爬取的URL。其支持嵌套的sitemap,并能從robots.txt會獲取sitemap的url。
sitemap_urls包含你要爬取的url的sitemap的url列表。也可以指定為一個robots.txt,spider會從中分析并提取url。
sitemap_rules一個包含(regex,callback)元組的列表。
- regex是一個用于匹配從sitemap提供的url的正則表達式;可以是一個字符串或者編譯的正則對象。
- callback指定了匹配正則表達式的url的處理函數??梢允且粋€字符串或者callale。規則按順序進行匹配,之后第一個匹配才會被應用。如果忽略該屬性,sitemap中發現的所有url將會被parse函數處理。
- sitemap_follow一個用于匹配要跟進的sitemap的正則表達式的列表。其僅僅被應用在使用Sitemap index files來指向其他sitemap文件的站點。默認情況下所有的sitemap都回被跟進。
- sitemap_alternate_links指定當一個url又可選的鏈接時,是否跟進。有些非英文網站會在一個url塊內提供其他語言的網站鏈接。
當 sitemap_alternate_links 設置時,兩個URL都會被獲取。 當 sitemap_alternate_links 關閉時,只有 http://example.com/ 會被獲取。默認 sitemap_alternate_links 關閉。
樣例
使用parse處理通過sitemap發現的所有url:
用特定的函數處理某些url,其他的使用另外的callback:
from scrapy.contrib.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/sitemap.xml']sitemap_rules = [('/product/', 'parse_product'),('/category/', 'parse_category'),]def parse_product(self, response):pass # ... scrape product ...def parse_category(self, response):pass # ... scrape category ...跟進robots.txt文件定義的sitemap并只跟進包含有…sitemap_shop的url:
from scrapy.contrib.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/robots.txt']sitemap_rules = [('/shop/', 'parse_shop'),]sitemap_follow = ['/sitemap_shops']def parse_shop(self, response):pass # ... scrape shop here ...在SitemapSpider中使用其他url:
from scrapy.contrib.spiders import SitemapSpiderclass MySpider(SitemapSpider):sitemap_urls = ['http://www.example.com/robots.txt']sitemap_rules = [('/shop/', 'parse_shop'),]other_urls = ['http://www.example.com/about']def start_requests(self):requests = list(super(MySpider, self).start_requests())requests += [scrapy.Request(x, self.parse_other) for x in self.other_urls]return requestsdef parse_shop(self, response):pass # ... scrape shop here ...def parse_other(self, response):pass # ... scrape other here ...總結
以上是生活随笔為你收集整理的Scrapy——基本用法(命令行工具、Item、Spiders)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 现代公司理论在线考试习题
- 下一篇: 使用Arduino的自动药物提醒