python lxml模塊中xpath的學(xué)習(xí)

代碼為自學(xué)時所寫呀邢,如有錯誤铺遂,請不吝指教
xpath相關(guān)的基礎(chǔ)語法學(xué)習(xí)
lxml官方文檔介紹

  • lxml的安裝(我用的版本是4.1.1,python 3.5.2)

pip install lxml
//引用(下面是python3的引用格式)
from lxml import etree
  • 簡單的創(chuàng)建和遍歷

# 創(chuàng)建
root = etree.Element('root')
# 添加子元素,并為子節(jié)點添加屬性
root.append(etree.Element('child',interesting='sss'))
# 另一種添加子元素的方法
body = etree.SubElement(root,'body')
body.text = 'TEXT' # 設(shè)置值
body.set('class','dd') # 設(shè)置屬性
//
# 輸出整個節(jié)點
print(etree.tostring(root, encoding='UTF-8', pretty_print=True))
//
//
# 創(chuàng)建,添加子節(jié)點腥寇、文本、注釋
root = etree.Element('root')
etree.SubElement(root, 'child').text = 'Child 1'
etree.SubElement(root, 'child').text = 'Child 2'
etree.SubElement(root, 'child').text = 'Child 3'
root.append(etree.Entity('#234'))
root.append(etree.Comment('some comment'))  # 添加注釋
# 為第三個節(jié)點添加一個br
br = etree.SubElement(root.getchildren()[2],'br')
br.tail = 'TAIL'
for element in root.iter(): # 也可以指定只遍歷是Element的觅捆,root.iter(tag=etree.Element)
   if isinstance(element.tag, str):
        print('%s - %s' % (element.tag, element.text))
    else:
        print('SPECIAL: %s - %s' % (element, element.text))
  • 對HTML/XML的解析

# 先導(dǎo)入相關(guān)模塊
from lxml import etree
from io import StringIO, BytesIO
# 對html具有修復(fù)標(biāo)簽補全的功能
broken_html = '<html><head><title>test<body><h1 class="hh">page title</h3>'
parser = etree.HTMLParser()
tree = etree.parse(StringIO(broken_html), parser) # 或者直接使用 html = etree.HTML(broken_html)
print(etree.tostring(tree, pretty_print=True, method="html"))
#
#
#用xpath獲取h1
h1 = tree.xpath('//h1')  # 返回的是一個數(shù)組
# 獲取第一個的tag
print(h1[0].tag)
# 獲取第一個的class屬性
print(h1[0].get('class'))
# 獲取第一個的文本內(nèi)容
print(h1[0].text)
# 獲取所有的屬性的key赦役,value的列表
print(h1[0].keys(),h1[0].values())
  • 使用xpath的一個小示例

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

from lxml import etree


class LearnXpath(object):
    """
    python 中 lxml模塊的 xpath學(xué)習(xí)
    """

    def __init__(self, fileName='./example.html'):
        self.htmlParser = etree.HTMLParser(remove_comments=True, compact=True, encoding='UTF-8')
        self.root = etree.parse(fileName, self.htmlParser)

    # 打印html的內(nèi)容
    def __str__(self):
        return str(etree.tostring(self.root, pretty_print=True, method='html'), encoding='UTF-8')

    __repr__ = __str__

    # 查出頭像圖片的alt和src, 并去重頭像的地址
    def listAuthorImg(self, printFlag=True):
        imgList = self.root.xpath('//div[@id="list-container"]//div[@class="author"]//img')
        s = set()
        if printFlag:
            for img in imgList:
                if img.get('src') in s:
                    continue
                else:
                    s.add(img.get('src'))
                    print('alt=%s, src=%s' % (img.get('alt'), 'http:' + img.get('src')))
        else:
            return imgList

    # 查詢圖片中,alt>100的所有圖片栅炒, 并去重
    def listImgAltBig100(self, printFlag=True):
        imgList = self.root.xpath('//div[@id="list-container"]//li//img[number(@alt)>100]')
        s = set()
        if printFlag:
            for img in imgList:
                if img.get('src') in s:
                    continue
                else:
                    s.add(img.get('src'))
                    print('alt=%s, src=%s' % (img.get('alt'), 'http:' + img.get('src')))

    # 獲取文章列表的title和鏈接地址
    def listArticle(self, printFlag=True):
        articleList = self.root.xpath('//div[@id="list-container"]//li//a[@class="title"]')
        if printFlag:
            for article in articleList:
                print('title=%s, src=%s' % ('《'+article.text + '》', 'http://www.reibang.com'+article.get('href')))
        else:
            return articleList

    # 獲取文章名稱的列表  在htmlParser中需要指定encoding='UTF-8' 掂摔,不然,獲取的是亂碼
    def listArticleTitle(self, printFlag=True):
        titleList = self.root.xpath('//div[@id="list-container"]//li//a[@class="title"]/text()')
        if printFlag:
            for title in titleList:
                print('《' + title + '》')
        else:
            return titleList

    # 獲取文章的所有的鏈接地址
    def listArticleHref(self, printFlag=True):
        hrefList = self.root.xpath('//div[@id="list-container"]//li//a[@class="title"]/@href')
        if printFlag:
            for href in hrefList:
                print('http://www.reibang.com'+href)
        else:
            return hrefList

    # 獲取文章的id
    def listArticleId(self, printFlag=True):
        idList = self.root.xpath('//div[@id="list-container"]/ul/li/@data-note-id')
        if printFlag:
            for id in idList:
                print(id)

    # 獲取第三篇文章的title和鏈接
    def getThirdArticle(self, printFlag=True):
        # 最后一篇 //div[@id="list-container"]/ul/li[last()]//a[@class="title"]
        # 倒數(shù)第二篇 //div[@id="list-container"]/ul/li[last()-1]//a[@class="title"]
        thirdArticle = self.root.xpath('//div[@id="list-container"]/ul/li[3]//a[@class="title"]')
        if printFlag:
            print('title=%s, src=%s' % ('《' + thirdArticle[0].text + '》', 'http://www.reibang.com' + thirdArticle[0].get('href')))
        else:
            return thirdArticle

    # 獲取前三篇文章的title和鏈接
    def listthreeArticle(self, printFlag=True):
        articleList = self.root.xpath('//div[@id="list-container"]/ul/li[position()<4]//a[@class="title"]')
        if printFlag:
            for article in articleList:
                print('title=%s, src=%s' % ('《' + article.text + '》', 'http://www.reibang.com' + article.get('href')))
        else:
            return articleList

    # 獲取瀏覽量大于n的文章的標(biāo)題和地址
    def listArticleByFilter(self, printFlag=True, n=1000):
        scanList = self.root.xpath('//div[@id="list-container"]//li//div[@class="meta"]/a[1]')  # 獲取所有的瀏覽量的 a 標(biāo)簽
        if printFlag:
            for sc in scanList:
                textList = sc.xpath('./text()')  # 獲取a 的文本职辅, 文本內(nèi)容基本上均是['\n',' 181\n        ']
                for txt in textList:
                    try:
                        # print(txt)
                        txt = txt[:txt.index('\n')].strip()  # 以\n分割棒呛,并去除前后空格
                        # print(txt)
                        scanCount = int(txt)  # 轉(zhuǎn)換成int類型
                        if scanCount > n:
                            # print(scanCount)
                            # 獲取 a標(biāo)簽的父元素<div class="meta"> ,然后再獲取該同級元素a[class="title"]
                            titleA = sc.xpath('./ancestor::div[@class="meta"]/preceding-sibling::a[@class="title"]')
                            # print(etree.tostring(titleA[0]))
                            print('scanCount=%d, title=%s, src=%s' % (scanCount, '《' + titleA[0].text + '》', 'http://www.reibang.com'+titleA[0].get('href')))
                    except:
                        # print(e)
                        continue
        else:
            return 0


if __name__ == '__main__':
    lx = LearnXpath()
    # print(lx)
    # 打印頭像圖片的大小域携,以及地址
    lx.listAuthorImg(False)
    # 選取 圖片 alt大于100的
    lx.listImgAltBig100(False)
    # 所有文章的title和鏈接
    lx.listArticle(False)
    # 所有文章的標(biāo)題
    lx.listArticleTitle(False)
    # 所有文章的鏈接
    lx.listArticleHref(False)
    # 所有文章的id
    lx.listArticleId(False)
    # 獲取第三篇文章的title和鏈接
    lx.getThirdArticle(False)
    # 獲取前三篇文章的title和鏈接
    lx.listthreeArticle(False)
    # 獲取瀏覽量大于1000的文章
    lx.listArticleByFilter(printFlag=False)

點擊獲取示例使用的html代碼片段

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鱼喉,隨后出現(xiàn)的幾起案子秀鞭,更是在濱河造成了極大的恐慌,老刑警劉巖扛禽,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锋边,死亡現(xiàn)場離奇詭異,居然都是意外死亡编曼,警方通過查閱死者的電腦和手機豆巨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掐场,“玉大人往扔,你說我怎么就攤上這事贩猎。” “怎么了萍膛?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵吭服,是天一觀的道長。 經(jīng)常有香客問我蝗罗,道長艇棕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任串塑,我火速辦了婚禮沼琉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桩匪。我一直安慰自己刺桃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布吸祟。 她就那樣靜靜地躺著瑟慈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屋匕。 梳的紋絲不亂的頭發(fā)上葛碧,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音过吻,去河邊找鬼进泼。 笑死,一個胖子當(dāng)著我的面吹牛纤虽,可吹牛的內(nèi)容都是我干的乳绕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼逼纸,長吁一口氣:“原來是場噩夢啊……” “哼洋措!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杰刽,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤菠发,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贺嫂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滓鸠,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年第喳,在試婚紗的時候發(fā)現(xiàn)自己被綠了糜俗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖悠抹,靈堂內(nèi)的尸體忽然破棺而出珠月,到底是詐尸還是另有隱情,我是刑警寧澤锌钮,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布桥温,位于F島的核電站,受9級特大地震影響梁丘,放射性物質(zhì)發(fā)生泄漏侵浸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一氛谜、第九天 我趴在偏房一處隱蔽的房頂上張望掏觉。 院中可真熱鬧,春花似錦值漫、人聲如沸澳腹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酱塔。三九已至,卻和暖如春危虱,著一層夾襖步出監(jiān)牢的瞬間羊娃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工埃跷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蕊玷,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓弥雹,卻偏偏與公主長得像垃帅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剪勿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

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