Python爬蟲:現(xiàn)學(xué)現(xiàn)用xpath爬取豆瓣音樂(lè)

教程來(lái)自于大神@逆水寒python綠色通道

from lxml import etree
s=etree.HTML(源碼) #將源碼轉(zhuǎn)化為能被XPath匹配的格式
s.xpath(xpath表達(dá)式) #返回為一列表

基礎(chǔ)語(yǔ)法

1.// 雙斜杠 定位根節(jié)點(diǎn)拴驮,會(huì)對(duì)全文進(jìn)行掃描,在文檔中選取所有符合條件的內(nèi)容呻征,以列表的形式返回葛躏。
2./ 單斜杠 尋找當(dāng)前標(biāo)簽路徑的下一層路徑標(biāo)簽或者對(duì)當(dāng)前路標(biāo)簽內(nèi)容進(jìn)行操作
3./text() 獲取當(dāng)前路徑下的文本內(nèi)容
4./@xxxx 提取當(dāng)前路徑下標(biāo)簽的屬性值
5.| 可選符 使用|可選取若干個(gè)路徑 如//p | //div 即在當(dāng)前路徑下選取所有符合條件的p標(biāo)簽和div標(biāo)簽养铸。
6.'.' 點(diǎn) 用來(lái)選取當(dāng)前節(jié)點(diǎn)
7 .'..' 雙點(diǎn) 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)

xpath簡(jiǎn)單獲取音樂(lè)標(biāo)題

打開網(wǎng)址,按下F12戒悠,然后查找標(biāo)題熬荆,右鍵彈出菜單欄 Copy==> Copy Xpath

ixpath獲取標(biāo)題路徑.png

音樂(lè)標(biāo)題xpath獲取的路徑是://*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div/a
代碼如下:

# coding:utf-8
from lxml import etree
import requests

url = 'https://music.douban.com/top250'

html = requests.get(url).text  # 打印一下 網(wǎng)頁(yè)內(nèi)容,看是否有內(nèi)容再繼續(xù)
s = etree.HTML(html)
title = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a')   # 多余的/tbody刪除绸狐,否則打印的內(nèi)容為空
print title
得到結(jié)果
------------------------------
[<Element a at 0x3cd1b48>]

這里需要注意一下卤恳,瀏覽器復(fù)制的xpath只能作參考,因?yàn)闉g覽器經(jīng)常會(huì)在自己里面增加多余的tbody標(biāo)簽寒矿,我們需要手動(dòng)把這個(gè)標(biāo)簽刪除
刪除中間的/tbody后,是這樣的突琳,
title = s.xpath('//[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a')
然后我們?cè)龠\(yùn)行代碼。
得到:
[<Element a at 0x3cd1b48>]
說(shuō)明標(biāo)題被獲取到了符相。
因?yàn)橐@取標(biāo)題文本拆融,所以xpath表達(dá)式要追加/text()
title = s.xpath('//
[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/text()')#因?yàn)橐@取標(biāo)題,所以我需要這個(gè)當(dāng)前路徑下的文本啊终,所以使用/text()

又因?yàn)檫@個(gè)s.xpath返回的是一個(gè)集合镜豹,且集合中只有一個(gè)元素所以我再追加一個(gè)[0]
新的表達(dá)式:
title = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/text()')[0]#因?yàn)橐@取標(biāo)題,所以我需要這個(gè)當(dāng)前路徑下的文本蓝牲,所以使用/text(),再追加[0]

重新運(yùn)行得到結(jié)果:
We Sing. We Dance. We Steal Things.
正是我們想要的標(biāo)題逛艰。

2.獲取評(píng)價(jià)評(píng)分和評(píng)價(jià)人數(shù)

老方法xpath獲取路徑
評(píng)分路徑://[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/div/span[2]
評(píng)論人數(shù)路徑://
[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/div/span[3]/text()

3.獲取音樂(lè)的鏈接

這里我們就用到了知識(shí)點(diǎn),路徑下的屬性值@XXX
xpath路徑://*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/@href

4.獲取圖片地址

同上老方法
xpath路徑://*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[1]/a/img/@src
這里犯了一個(gè)錯(cuò)誤搞旭,路徑檢查不徹底散怖。引以為戒


圖片路徑

運(yùn)行代碼如下:

# coding:utf-8
from lxml import etree
import requests

url = 'https://music.douban.com/top250'

html = requests.get(url).text  # 打印一下 網(wǎng)頁(yè)內(nèi)容,看是否有內(nèi)容再繼續(xù)
s = etree.HTML(html)
title = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/text()')[0]  # 多余的/tbody刪除肄渗,否則打印的內(nèi)容為空
score = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/div/span[2]/text()')[0]
numbers = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/div/span[3]/text()')[0]
href = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/@href')[0]
img = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[1]/a/img/@src')[0]
print title, score, numbers, href, img
------------------------------------------
 We Sing. We Dance. We Steal Things.
        9.1 
                    (
                            100933人評(píng)價(jià)
                    )
                 https://music.douban.com/subject/2995812/
 https://img3.doubanio.com/view/subject/s/public/s

上面我知識(shí)獲取了一條數(shù)據(jù)镇眷,如何獲取多條數(shù)據(jù)呢?
對(duì)比標(biāo)題的路徑
We Sing. We Dance. We Steal Things.://[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a
Viva La Vida Death And All His Friends://
[@id="content"]/div/div[1]/div/table[2]/tr/td[2]/div/a

運(yùn)行代碼:

# coding:utf-8
from lxml import etree
import requests

url = 'https://music.douban.com/top250'


html = requests.get(url).text
s = etree.HTML(html)
title = s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div/a/text()')[0]#因?yàn)橐@取標(biāo)題翎嫡,所以我需要這個(gè)當(dāng)前路徑下的文本欠动,所以使用/text()
title2 = s.xpath('//*[@id="content"]/div/div[1]/div/table[2]/tr/td[2]/div/a/text()')[0]#因?yàn)橐@取標(biāo)題,所以我需要這個(gè)當(dāng)前路徑下的文本,所以使用/text()
title3 = s.xpath('//*[@id="content"]/div/div[1]/div/table[3]/tr/td[2]/div/a/text()')[0]#因?yàn)橐@取標(biāo)題具伍,所以我需要這個(gè)當(dāng)前路徑下的文本翅雏,所以使用/text()
title4 = s.xpath('//*[@id="content"]/div/div[1]/div/table[4]/tr/td[2]/div/a/text()')[0]#因?yàn)橐@取標(biāo)題,所以我需要這個(gè)當(dāng)前路徑下的文本人芽,所以使用/text()
print title,title2,title3,title4
---------------------------------
 We Sing. We Dance. We Steal Things.
        Viva La Vida
        華麗的冒險(xiǎn)
        范特西

對(duì)比他們的xpath望几,發(fā)現(xiàn)只有table序號(hào)不一樣,我們可以就去掉序號(hào)萤厅,得到通用的xpath信息://*[@id="content"]/div/div[1]/div/table/tr/td[2]/div/a

同理橄抹,評(píng)論,評(píng)論人數(shù)都采用這個(gè)方法
運(yùn)行代碼如下

itles = s.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div/a/text()') # 因?yàn)橐@取標(biāo)題惕味,所以我需要這個(gè)當(dāng)前路徑下的文本楼誓,所以使用/text()
scores = s.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div/div/span[2]/text()')
for title in titles:
    print title.strip()
for score in scores:
    print score.strip()
-------------------------------------------------
We Sing. We Dance. We Steal Things.
Viva La Vida

華麗的冒險(xiǎn)

范特西

後。青春期的詩(shī)

是時(shí)候

Lenka
Start from Here

旅行的意義
太陽(yáng)

Once (Soundtrack)

Not Going Anywhere

American Idiot
OK

無(wú)與倫比的美麗

親愛(ài)的...我還不知道

城市

O
Wake Me Up When September Ends

葉惠美

七里香

21
My Life Will...
寓言
你在煩惱什么

9.1
8.7
8.9
9.2
8.8
8.6
8.5
8.7
9.2
8.6
9.1
8.9
8.9
8.8
8.6
8.5
8.3
9.1
9.3
8.5
8.1
9.0
8.6
9.3
8.9

我們(大神發(fā)現(xiàn)的)也發(fā)現(xiàn)了問(wèn)題每一個(gè)xpath路徑特別長(zhǎng)名挥,能不能精簡(jiǎn)一下呢疟羹?

xpath路徑

觀察發(fā)現(xiàn)獲取幾個(gè)關(guān)鍵字段的xpath前綴都是 //*[@id="content"]/div/div[1]/div/table/tr 那我能不能把這些東西提出來(lái)呢,讓后面的不同的自己去追加禀倔,另外這樣寫也不用管每個(gè)頁(yè)面到底有多少條數(shù)據(jù)阁猜,只管查就行了。所以代碼做了一下精簡(jiǎn)

運(yùn)行代碼如下:

trs = s.xpath('//*[@id="content"]/div/div[1]/div/table/tr')   # 先提取tr之前的節(jié)點(diǎn)集合

for tr in trs:
    title = tr.xpath('td[2]/div/a/text()')[0]  # 注意新節(jié)點(diǎn)是tr下的節(jié)點(diǎn)
    score = tr.xpath('td[2]/div/div/span[2]/text()')[0]
    print title, score

運(yùn)行結(jié)果一樣


精簡(jiǎn)的結(jié)果

獲取多個(gè)頁(yè)面的數(shù)據(jù)

觀察一下翻頁(yè)路徑:
https://music.douban.com/top250?start=0
https://music.douban.com/top250?start=25
https://music.douban.com/top250?start=50

有沒(méi)有發(fā)現(xiàn)頁(yè)面只是后面start參數(shù)發(fā)生了改變蹋艺,且增長(zhǎng)為每次25剃袍,并且250條數(shù)據(jù)正好是10頁(yè)。
所以我可以遍歷這個(gè)頁(yè)面捎谨。
完整代碼:

def getUrl():
    for i in range(10):
        url = 'https://music.douban.com/top250?start={}'.format(i*25)
        scrapypage(url)

def scrapypage(url):
    html = requests.get(url).text
    s = etree.HTML(html)
    trs = s.xpath('//*[@id="content"]/div/div[1]/div/table/tr')

    for tr in trs:
        title = tr.xpath('td[2]/div/a/text()')[0]
        print title

if '__main__':
    getUrl()

結(jié)果很完美


截圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末民效,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涛救,更是在濱河造成了極大的恐慌畏邢,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件检吆,死亡現(xiàn)場(chǎng)離奇詭異舒萎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蹭沛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門臂寝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人摊灭,你說(shuō)我怎么就攤上這事咆贬。” “怎么了帚呼?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵掏缎,是天一觀的道長(zhǎng)皱蹦。 經(jīng)常有香客問(wèn)我,道長(zhǎng)眷蜈,這世上最難降的妖魔是什么沪哺? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮酌儒,結(jié)果婚禮上辜妓,老公的妹妹穿的比我還像新娘。我一直安慰自己今豆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布柔袁。 她就那樣靜靜地躺著呆躲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捶索。 梳的紋絲不亂的頭發(fā)上插掂,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音腥例,去河邊找鬼辅甥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛燎竖,可吹牛的內(nèi)容都是我干的璃弄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼构回,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夏块!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起纤掸,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤脐供,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后借跪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體政己,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年掏愁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歇由。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡果港,死狀恐怖印蓖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情京腥,我是刑警寧澤赦肃,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響他宛,放射性物質(zhì)發(fā)生泄漏船侧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一厅各、第九天 我趴在偏房一處隱蔽的房頂上張望镜撩。 院中可真熱鬧,春花似錦队塘、人聲如沸袁梗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)遮怜。三九已至,卻和暖如春鸿市,著一層夾襖步出監(jiān)牢的瞬間锯梁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工焰情, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陌凳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓内舟,卻偏偏與公主長(zhǎng)得像合敦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子验游,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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