二. Scrapy常用函數(shù)及方法

1.spider開發(fā)流程:

  • 最簡單的Spider只需4個步驟:
    1).繼承scrapy.Spider派诬;
    2).為Spider取名盟萨;
    3).設置爬取的起始點吝羞;
    4).實現(xiàn)頁面解析函數(shù)兰伤。

其中,Spider是一個基類钧排,后面我們使用到的所有其他爬蟲都需要繼承這個Spider基類敦腔,例如:CrawlSpider,XMLFeedSpider恨溜,CSVFeedSpider符衔,SitemapSpider等找前,這些類全部位于scrapy\spiders目錄之下。

實際上設置完爬取起始點后判族,默認由start_reqeusts()方法構建Request對象躺盛,然后默認指定由parse方法作為頁面解析函數(shù)。如果我們希望為Request添加特定的請求頭部或想為Request指定特定的頁面解析函數(shù)形帮,可以考慮在構建的Spider類中實現(xiàn)start_requests方法槽惫,即可覆蓋基類Spider的start_requests方法。例如辩撑,在第一章的基礎上進行修改:

import scrapy

class Books(scrapy.Spider):
    name = 'books'
    #start_urls = ['http://books.toscrape.com/']

    #實現(xiàn)start_requests方法界斜,替代start_urls這個類屬性
    def start_requests(self):
        yield scrapy.Request(url="http://books.toscrape.com/",
                             callback=self.parse_book,    #此時改用parse_book作為回調函數(shù)
                             headers={'User-Agent':'Mozilla/5.0'},
                             dont_filter=True)

    def parse_book(self,response):
        infos = response.xpath('//article')
        for info in infos:
            title = info.xpath("h3/a/@title").extract()[0]
            price = info.xpath('div/p[@class="price_color"]/text()').extract()[0]

            yield {'title': title, 'price': price}   

所以,設置爬取的起爬點有兩種方法:

  • 定義start_urls屬性
  • 改寫start_requests方法

而第四個步驟合冀,頁面解析函數(shù)需要完成以下兩個工作:
1).提取數(shù)據(jù)各薇,將數(shù)據(jù)封裝后(Item或字典)提交給Scrapy引擎;
2).提取鏈接水慨,并用鏈接構造新的Request對象提交給Scrapy引擎得糜;其中,提取鏈接的方法包括使用選擇器或使用LinkExtractor晰洒。

2.常用方法

1)提取常用方法
.extract() 對結果以列表的形式進行返回
.extract_first() 對extract()返回的結果列表取第一個元素朝抖。
.re() #對結果使用正則表達式進行再提取
.re_first() #返回第一個re()結果。

2)調用selector的方法
selector類的實現(xiàn)位于scrapy.selector模塊谍珊,通過創(chuàng)建對象即可使用css或xpath解析方法治宣。

from scrapy.selector import Selector

class Book(scrapy.Spider):
    ...
    
    def parse(self,response):
        selector = Selector(response)
        infos = selector.xpath("http://h1")
        ...

當然,實際開發(fā)中砌滞,我們無需創(chuàng)建Selector對象侮邀,因為當我們第一次訪問Response對象的selector屬性時,Response對象會自動創(chuàng)建Selector對象贝润,同時在Response對象中內置了selector對象的css和xpath方法以供使用绊茧。

class Book(scrapy.Spider):
    ...

    def parse(self,response):
        infos = response.xpath("http://h1")

3)使用Item封裝數(shù)據(jù)(items.py)
相對于使用字典來維護數(shù)據(jù)信息,使用item封裝數(shù)據(jù)打掘,有以下好處:
①清楚了解數(shù)據(jù)中包含哪些字段华畏;
②包含對字段名字的檢測;
③方便攜帶元數(shù)據(jù)尊蚁,用于傳遞給其他組件的信息亡笑;

  • 數(shù)據(jù)段的基類:Item基類
  • 描述數(shù)據(jù)包含哪些字段的類:FIeld類
    在items.py中這樣寫:
from scrapy import Item,Field

class BooksItem(Item):
    title = Field()
    price = Field()

在project為books,spiders文件夾下的books.py下這樣寫:

from books.items import BooksItem     #引入items.py中創(chuàng)建的對象
    def parse_book(self,response):
        infos = response.xpath('//article')
        book = BooksItem()   #實例化BooksItem()
        for info in infos:
            book['title'] = info.xpath("h3/a/@title").extract()[0]
            book['price'] = info.xpath('div/p[@class="price_color"]/text()').extract()[0]

            yield book      #返回book

4)使用Item Pipeline處理數(shù)據(jù)(pipelines.py)
Item Pipeline的幾種典型應用:

  • 清洗數(shù)據(jù)
  • 驗證數(shù)據(jù)的有效性
  • 過濾重復的數(shù)據(jù)
  • 將數(shù)據(jù)存入數(shù)據(jù)庫

①Item Pipeline不需要繼承特定基類横朋,只需要實現(xiàn)特定方法仑乌,例如:process_item、open_spider、close_spider晰甚。
②一個Item Pipeline必須實現(xiàn)一個process_item(item,spider)方法衙传,該方法用來處理每一項由Spider爬取到的數(shù)據(jù),其中兩個參數(shù):
item: 爬取到的一項數(shù)據(jù)(Item或字典)
spider:爬取此項數(shù)據(jù)的Spider對象
例如將Sharp Objects,£47.82中的英鎊轉換成人民幣Sharp Objects,¥406.47压汪。
代碼為:

class PriceConverterPipeline(object):
    
    exchange_rate = 8.5  #英鎊對人民幣匯率
    
    def process_item(self, item, spider):
        price = item['price'][1:] * self.exchange_rate
        item['price'] = price
        
        return item

寫入MongoDB的代碼粪牲,方式一:

import pymongo

class MongoDBPipeline(object):
    def __init__(self):
        client = pymongo.MongoClient('localhost',27017)
        test = client['test']
        book = test['book']
        self.post = book
        
    def process_item(self,item,spider):
        info = dict(item)
        self.post.insert(info)
        return item

寫入MongoDB的代碼,方式二:

import pymongo

class MongoDBPipeline(object):
    DB_URI = 'mongodb://localhost:27017/'
    DB_NAME = 'test'
    
    def open_spider(self,spider):
        self.client = pymongo.MongoClient(self.DB_URI)
        self.db = self.client[self.DB_NAME]
        
    def close_spider(self,spider):
        self.client.close()

    def process_item(self, item, spider):
        collection = self.db['book']
        post = dict(item)
        collection.insert_one(post)
        return item

過濾重復數(shù)據(jù)止剖,這里以書名作為主鍵判斷重復項,實際上應該以ISBN編號為主鍵落君,只是前面僅爬取了書名和價格穿香。

from scrapy.exceptions import DropItem

class DuplicatesPipeline(object):
    def __init__(self):
        self.book_set = set()
        
    def process_item(self,item,spider):
        name = item['name']
        if name in self.book_set:
            raise DropItem('Duplicate book found:%s' %item)
        self.book_set.add(name)
        return item

由于Item Pipeline是可選的組件,想要啟用某個Item Pipeline绎速,需要在settings.py中可對Item Pipeline進行設置皮获。
例如:

ITEM_PIPELINES = {
   'books.pipelines.PriceConverterPipeline': 300,
   'books.pipelines.MongoDBPipeline': 500,
   'books.pipelines.DuplicatesPipeline': 400,
}

其中,字典中的key為導入路徑纹冤,后面的value是0~1000的數(shù)字洒宝。如果同時啟動多個Pipeline,優(yōu)先處理數(shù)字最小的Pipeline萌京。

5)使用LinkExtractor提取鏈接
提取鏈接信息有兩種方法雁歌,簡單少量的鏈接使用Selector就足夠了,而對于大量的鏈接或者復雜規(guī)則的鏈接知残,使用LinkExtractor更方便靠瞎。
下面是代碼的比較:

  • Selector()
next_url = response.xpath('//li[@class="next"]/a/@href').extract()[0]
if next_url:
    next_url = response.urljoin(next_url)
    yield scrapy.Request(next_url,callback=self.parse)
  • LinkExtractor()
from scrapy.linkextractors import LinkExtractor
next = LinkExtractor(restrict_xpaths='//li[@class="next"]')  #LinkExtractor中添加限制條件,如果為空會提取頁面的所有鏈接
links = next.extract_links(response)  #返回一個Link對象的列表求妹,里面包含鏈接乏盐。
if links:
    next_url = links[0].url   #next_url[0]可獲取Link對象,Link對象的url屬性就是絕對地址制恍,無需自己構建相對地址父能。
    yield scrapy.Request(next_url,callback=self.parse)

6)使用Exporter導出數(shù)據(jù)(settings.py)

  • 可以使用命令行參數(shù)指定
  • 通過配置文件指定

命令行: scrapy crawl -o books.csv
scrapy crawl -o books.csv -t csv ## -t可以省略

配置文件:

選項 含義 示例
FEED_URI 導出文件路徑 FEED_URI = 'books.csv'
FEED_FORMAT 導出數(shù)據(jù)格式 FEED_FORMAT = 'csv'
FEED_EXPORT_ENCODING 導出文件編碼方式 FEED_EXPORT_ENCODING='gbk'
FEED_EXPORT_FIELDS 指定導出哪些字段并排序 FEED_EXPORT_FIELDS={'title','price'}
FEED_EXPORTERS 用戶自定義Exporter字典,一般用于添加新的導出數(shù)據(jù)格式 FEED_EXPORTERS ={‘excel’:'項目名.新設置的py文件名.ExcelItemExporter'}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末净神,一起剝皮案震驚了整個濱河市何吝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌强挫,老刑警劉巖岔霸,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異俯渤,居然都是意外死亡呆细,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來絮爷,“玉大人趴酣,你說我怎么就攤上這事】雍唬” “怎么了岖寞?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柜蜈。 經常有香客問我仗谆,道長,這世上最難降的妖魔是什么淑履? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任隶垮,我火速辦了婚禮,結果婚禮上秘噪,老公的妹妹穿的比我還像新娘狸吞。我一直安慰自己,他們只是感情好指煎,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布蹋偏。 她就那樣靜靜地躺著,像睡著了一般至壤。 火紅的嫁衣襯著肌膚如雪威始。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天崇渗,我揣著相機與錄音字逗,去河邊找鬼。 笑死宅广,一個胖子當著我的面吹牛葫掉,可吹牛的內容都是我干的。 我是一名探鬼主播跟狱,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俭厚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了驶臊?” 一聲冷哼從身側響起挪挤,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎关翎,沒想到半個月后扛门,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡纵寝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年论寨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡葬凳,死狀恐怖绰垂,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情火焰,我是刑警寧澤劲装,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站昌简,受9級特大地震影響占业,放射性物質發(fā)生泄漏。R本人自食惡果不足惜纯赎,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一纺酸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧址否,春花似錦、人聲如沸碎紊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仗考。三九已至音同,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秃嗜,已是汗流浹背权均。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锅锨,地道東北人叽赊。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像必搞,于是被迫代替她去往敵國和親必指。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內容

  • scrapy是python最有名的爬蟲框架之一恕洲,可以很方便的進行web抓取塔橡,并且提供了很強的定制型,這里記錄簡單學...
    bomo閱讀 2,121評論 1 11
  • 創(chuàng)建一個Scrapy項目 1.創(chuàng)建項目文件夾tutorial 2.創(chuàng)建Spider類 Spider的用法 使用命令...
    天涼玩?zhèn)€錘子閱讀 445評論 0 1
  • scrapy框架Scrapy是用純Python實現(xiàn)一個為了爬取網站數(shù)據(jù)霜第、提取結構性數(shù)據(jù)而編寫的應用框架葛家,用途非常廣...
    糖炒栗子_01c5閱讀 2,897評論 0 2
  • 《遇見未知的自己》中若菱面臨家庭和事業(yè)的雙危機癞谒,在老人的引導下,通過找出真我的特質(愛、喜悅扯俱、和平)书蚪,運用瑜...
    顏如玉88閱讀 224評論 0 0
  • 4月14日 星期五 陰轉晴 今天放學回家,爸爸帶我們去外面吃飯迅栅,為了慶祝媽媽科三考試通過了殊校。吃完飯,我們...
    A葉瑞妹閱讀 216評論 2 2