1. 程式人生 > >lxml解析html時,檢驗XPath

lxml解析html時,檢驗XPath

這兩天在研究Scrapy,在遇到用Xpath提出時,需要有Chrome的XPath helper,但老是出現錯誤。廢話少說,還是先把測試網頁儲存到本地,逐步的測試提取。

測試文字text.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>測試-常規方法</title>
</head>
<body>
<div id="content">
    <ul id="useful"
>
<li>這是第一條資訊</li> <li>這是第二條資訊</li> <li>這是第三條資訊</li> </ul> <ul id="useless"> <li>不需要的資訊1</li> <li>不需要的資訊2</li> <li>不需要的資訊3</li> </ul> <div id="url"
>
<a href="http://jikexueyuan.com">極客學院</a> <a href="http://jikexueyuan.com/sourse/" title="極客學院課程庫">點我開啟課程庫</a> </div> </div> <div id="test-0">大家好!</div> <div id="test-1">需要的內容1</div> <div id="test-2">需要的內容2</div> <div
id="testfault">
需要的內容3</div> <div id="tiger"> 我左青龍, <span id="tiger2"> 右白虎, <ul> 上朱雀, <li>下玄武。</li> </ul> 老牛在當中, </span> 龍頭在胸口。 </div> <div id="test-3">美女, <font color=red>你的微信是多少?</font> </div> </body> </html>

使用XPath對相關內容的提取

# -*- coding: utf-8 -*-
from lxml import etree
f = open('text.html', 'r',encoding="utf-8")
html = f.read()
#print (html)
f.close()

selector = etree.HTML(html)

selector.xpath提取後為list

#提取單個文字
content = selector.xpath('//div[@id="test-0"]/text()')
print (content)

[‘大家好!’]

#提取多個文字
content = selector.xpath('//ul[@id="useful"]/li/text()')
print (content)
for each in content:
    print (each)

結果為:
這是第一條資訊
這是第二條資訊
這是第三條資訊

#提取屬性
link = selector.xpath('//a/@href')
for each in link:
    print (each)
#提取title
title = selector.xpath('//a/@title')
print (title[0])

結果為:
極客學院課程庫

# 以相同的字元開頭 starts-with(@屬性名稱,屬性字元相同部分)
content = selector.xpath('//div[starts-with(@id,"test")]/text()')
for each in content:
    print (each)

結果為:
大家好!
需要的內容1
需要的內容2
需要的內容3
美女,

#標籤套標籤,取出所有的標籤
data = selector.xpath('//div[@id="test-3"]')[0]
info = data.xpath('string(.)')
info=str(info)# info為<class 'lxml.etree._ElementUnicodeResult'>,轉為字元
content=" ".join(info.split())
print (content)

data = selector.xpath('//div[@id="tiger"]')[0]
info = data.xpath('string(.)')
info=str(info)# info為<class 'lxml.etree._ElementUnicodeResult'>,轉為字元
content=" ".join(info.split())
print (content)

結果為:
美女, 你的微信是多少?
我左青龍, 右白虎, 上朱雀, 下玄武。 老牛在當中, 龍頭在胸口。

注:這裡我將list轉為str。網上有許多其他方法加extract()我嘗試後,發現均出錯。
另外,發現網上的程式碼有問題。

data = selector.xpath('//div[@id="test3"]')info = data.xpath('string(.)').extract()[0]
這樣,就可以把“我左青龍,右白虎,上朱雀,下玄武。老牛在當中,龍頭在胸口”整個句子提取出來,賦值給info變數。

在IDE中直接測試

from lxml import etree
text="""
    <div class="bd doulist-subject">
        <div class="source">
            來自:豆瓣讀書
        </div>

        <div class="post">
            <a href="https://book.douban.com/subject/10519369/" target="_blank">
                <img width="100" src="https://img1.doubanio.com/lpic/s8869768.jpg">
            </a>
        </div>

        <div class="title">
            <a href="https://book.douban.com/subject/10519369/" target="_blank">
                萬物生光輝
            </a>
        </div>

        <div class="rating">
            <span class="allstar50"></span>
            <span class="rating_nums">9.4</span>
            <span>(738人評價)</span>
        </div>

        <div class="abstract">
        "
                作者: [英] 吉米·哈利
        <br>
        "
                出版社: 中國城市出版社
        <br>
        "
                出版年: 2012-3
            "
        </div>
    </div>

    """

selector = etree.HTML(text)

title = selector.xpath('//div[@class="title"]/a/text()')
title=title[0]
title=title.replace(" ","").replace("\\n","").replace("\\r","")
title=title.strip()
print (title)

rate = selector.xpath('//span[@class="rating_nums"]/text()')
rate=rate[0]
rate=rate.replace(" ","").replace("\\n","").replace("\\r","")
print (rate)

author = selector.xpath('//div[@class="abstract"]/text()')
author=author[0]
author=author.replace(" ","").replace("\\n","").replace("\\r","").replace('"',"")
author=author.strip()
print (author)