教程來(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
音樂(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)一下呢疟羹?
觀察發(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é)果一樣
獲取多個(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é)果很完美