爬蟲課堂(二十二)|使用LinkExtractor提取鏈接

在爬取一個(gè)網(wǎng)站時(shí)改衩,要爬取的數(shù)據(jù)通常不全是在一個(gè)頁(yè)面上驯镊,每個(gè)頁(yè)面包含一部分?jǐn)?shù)據(jù)以及到其他頁(yè)面的鏈接。比如前面講到的獲取簡(jiǎn)書文章信息橄镜,在列表頁(yè)只能獲取到文章標(biāo)題冯乘、文章URL及文章的作者名稱,如果要獲取文章的詳細(xì)內(nèi)容和文章的評(píng)論只能去到文章的詳情頁(yè)中獲取姊氓。
獲取數(shù)據(jù)的方法在前面章節(jié)中已經(jīng)講解過喷好,當(dāng)然也使用Selector獲取過文章URL,那么LinkExtractor又有什么特別之處呢棕孙?為什么說LinkExtrator非常適合整站抓刃┡颉?下面將對(duì)LinkExtrator做一個(gè)介紹肢预。
一洼哎、LinkExtractor基本使用
以獲取簡(jiǎn)書首頁(yè)的文章信息為例沼本,我們使用LinkExtractor提取網(wǎng)站上的鏈接锭沟,如圖22-1所示,提取的是class=note-list下的所有<li>中的鏈接辫红。

圖22-1

代碼如下:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import scrapy
from scrapy.linkextractor import LinkExtractor

class Jianshu(scrapy.Spider):
    name = "jianshu_spider"
    allowed_domains = ["jianshu.com"]

    def __init__(self, *args, **kwargs):
        super(Jianshu, self).__init__(*args, **kwargs)
        self.start_urls = ['http://www.reibang.com/']

    def parse(self, response):
        link = LinkExtractor(restrict_xpaths='//ul[@class="note-list"]/li')
        links = link.extract_links(response)
        if links:
            for link_one in links:
                print (link_one)

1)先使用from scrapy.linkextractor import LinkExtractor導(dǎo)入LinkExtractor贴妻。
2)創(chuàng)建一個(gè)LinkExtractor對(duì)象蝙斜,使用構(gòu)造器參數(shù)描述提取規(guī)則,這里是使用XPaths選擇器表達(dá)式給restrict_xpaths傳遞參數(shù)底循。
3)調(diào)用LinkExtractor對(duì)象的extract_links方法傳入一個(gè)Response對(duì)象槐瑞,該方法依據(jù)創(chuàng)建對(duì)象描述的提取規(guī)則在Response對(duì)象所包含的頁(yè)面中提取鏈接阁苞,并返回一個(gè)列表,列表中每個(gè)元素都是一個(gè)Link對(duì)象悼沿,即提取到的一個(gè)鏈接骚灸。

執(zhí)行上面的代碼,得到如下結(jié)果:

Link(url='http://www.reibang.com/p/29621e57077f', text='\n      \n    ', fragment='', nofollow=False)
Link(url='http://www.reibang.com/u/bfb1aa483a03', text='\n        \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/737d34bf3e55', text='\n            \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/29621e57077f#comments', text='\n           338\n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/c9185e45c4e2', text='\n      \n    ', fragment='', nofollow=False)
Link(url='http://www.reibang.com/u/cbd1e1bd402e', text='\n        \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/d1d89ed69098', text='\n            \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/c9185e45c4e2#comments', text='\n           80\n', fragment='', nofollow=False)
...
...
Link(url='http://www.reibang.com/p/1b638533689f', text='\n      \n    ', fragment='', nofollow=False)
Link(url='http://www.reibang.com/u/5428ad454a2c', text='\n        \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/1b638533689f#comments', text='\n           31\n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/9f18c99fb70c', text='\n      \n    ', fragment='', nofollow=False)
Link(url='http://www.reibang.com/u/a6c211083de3', text='\n        \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/9f18c99fb70c#comments', text='\n           39\n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/fdc53c576324', text='\n      \n    ', fragment='', nofollow=False)
Link(url='http://www.reibang.com/u/2b3ad4f2a058', text='\n        \n', fragment='', nofollow=False)
Link(url='http://www.reibang.com/p/fdc53c576324#comments', text='\n           33\n', fragment='', nofollow=False)

我們發(fā)現(xiàn)每個(gè)Link有一個(gè)url,可以通過link.url獲取鏈接信息非驮,如下代碼雏赦,把print link修改為print link.url

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import scrapy
from scrapy.linkextractor import LinkExtractor


class Jianshu(scrapy.Spider):
    name = "jianshu_spider"
    allowed_domains = ["jianshu.com"]

    def __init__(self, *args, **kwargs):
        super(Jianshu, self).__init__(*args, **kwargs)
        self.start_urls = ['http://www.reibang.com/']

    def parse(self, response):
        link = LinkExtractor(restrict_xpaths='//ul[@class="note-list"]/li')
        links = link.extract_links(response)
        if links:
            for link_one in links:
                print link_one.url

運(yùn)行之后得到的結(jié)果:

http://www.reibang.com/p/ee7e0647fb56
http://www.reibang.com/u/a7f876850fa6
http://www.reibang.com/p/d1d89ed69098
http://www.reibang.com/p/ee7e0647fb56#comments
...
...
http://www.reibang.com/p/2b55d55d2100
http://www.reibang.com/u/08529139a77b
http://www.reibang.com/p/2b55d55d2100#comments

以上就是LinkExtractor的基本使用,接下來繼續(xù)介紹LinkExtractor更多的提取參數(shù)方法填大。
二、更多的提取參數(shù)方法

  • allow:接收一個(gè)正則表達(dá)式或一個(gè)正則表達(dá)式列表圈浇,提取絕對(duì)url于正則表達(dá)式匹配的鏈接例获,如果該參數(shù)為空,默認(rèn)全部提取蠕搜。
def parse(self, response):
    pattern = '/gsschool/.+\.shtml'
    link = LinkExtractor(allow=pattern)
    links = link.extract_links(response)
  • deny:接收一個(gè)正則表達(dá)式或一個(gè)正則表達(dá)式列表收壕,與allow相反,排除絕對(duì)url于正則表達(dá)式匹配的鏈接虫埂,換句話說圃验,就是凡是跟正則表達(dá)式能匹配上的全部不提取。
def parse(self, response):
   pattern = '/gsschool/.+\.shtml'
   link = LinkExtractor(deny=pattern)
   links = link.extract_links(response)
  • allow_domains:接收一個(gè)域名或一個(gè)域名列表斧散,提取到指定域的鏈接摊聋。
def parse(self, response):
    domain = ['gaosivip.com','gaosiedu.com']
    link = LinkExtractor(allow_domains=domain)
    links = link.extract_links(response)
  • deny_domains:和allow_doains相反,拒絕一個(gè)域名或一個(gè)域名列表箍镜,提取除被deny掉的所有匹配url煎源。
def parse(self, response):
    domain = ['gaosivip.com','gaosiedu.com']
    link = LinkExtractor(deny_domains=domain)
    links = link.extract_links(response)
  • restrict_xpaths:上面的例子使用的就是這種方式,接收一個(gè)xpath表達(dá)式或一個(gè)xpath表達(dá)式列表脚草,提取xpath表達(dá)式選中區(qū)域下的鏈接原献。
  • restrict_css:和restrict_xpaths使用一樣埂淮,只是使用規(guī)則不一樣倔撞。
def parse(self, response):
    link = LinkExtractor(restrict_css='ul.note-list > li')
    links = link.extract_links(response)
  • tags:接收一個(gè)標(biāo)簽(字符串)或一個(gè)標(biāo)簽列表慕趴,提取指定標(biāo)簽內(nèi)的鏈接。
  • attrs:接收一個(gè)屬性(字符串)或者一個(gè)屬性列表冕房,提取指定的屬性內(nèi)的鏈接耙册。
def parse(self, response):
    link = LinkExtractor(tags='a',attrs='href')
    links = link.extract_links(response)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市帝际,隨后出現(xiàn)的幾起案子饶辙,更是在濱河造成了極大的恐慌,老刑警劉巖脯爪,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矿微,死亡現(xiàn)場(chǎng)離奇詭異冷冗,居然都是意外死亡惑艇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門思灌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恭取,“玉大人,你說我怎么就攤上這事耗跛。” “怎么了调塌?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵羔砾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我政溃,道長(zhǎng)态秧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任空扎,我火速辦了婚禮润讥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撮慨。我一直安慰自己脆粥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布规伐。 她就那樣靜靜地躺著匣缘,像睡著了一般肌厨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柑爸,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音馅而,去河邊找鬼。 笑死原押,一個(gè)胖子當(dāng)著我的面吹牛偎血,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笨农,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼谒亦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼空郊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狞甚,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤哼审,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后十气,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體春霍,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了离福。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炼蛤。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖絮识,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情熄攘,我是刑警寧澤彼念,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站哲思,受9級(jí)特大地震影響吩案,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜靠益,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一残揉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绩卤,春花似錦江醇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至本姥,卻和暖如春杭棵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工艰管, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒋川,地道東北人捺球。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像餐济,于是被迫代替她去往敵國(guó)和親胆剧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容