python爬蟲(三)xpath與lxml
阿新 • • 發佈:2019-02-12
XPath
XPath是一種在xml中查詢資訊的語言,可以用來在xml文件中對元素和屬性進行遍歷。
XPath使用路徑表示式在xml文件中選取節點,這裡注意需要逐級表現要選取節點的父子關係。
XPath符號
nodename
選取此節點的所有子節點/
從根節點選取//
從匹配選擇的當前節點文件中,而不考慮他們位置.
選取當前節點。..
選取當前節點的父節點@
選取屬性*
表示通配|
連線多個表示式,做並集操作
XPath路徑表達
bookstore
選取bookstore元素的所有子節點。/bookstore
選取根元素bookstore。
- 假如路徑起始於正斜槓 。註釋:假如路徑起始於正斜槓 。註釋:假如路徑起始於正斜槓 。註釋:假如路徑起始於正斜槓 ( / ( / ),則此路徑始 ,則此路徑始 終代表到某元素的絕對路徑!
bookstore/book
選取bookstore子元素中所有book元素。//book
選取所有book元素,而不管它們在文件中的位置。bookstore//book bookstore
選擇bookstore元素的後代中所有book元素,而不管它們位於bookstore下的什麼位置//@auth
選取所有名為auth的屬性
XPath謂語
謂語表達了針對該層級節點的篩選條件,常見謂語如下
/book[2]
表示在該級選取第二個book節點/book[last()]
表示在該級選取最後一個book節點/book[position()<5]
表示在該級選取前四個book節點/book[@auth]
/book[@auth="buka"]
表示在該級選取所有auth屬性值為buka
的book節點/book[price>35.00]
表示在該級選取price子元素的值大於35的book節點
lxml庫
lxml是一個用於靈活處理xml格式資料的庫,此處可以用來幫助做網頁解析。
lxml用來做網頁解析的時候最常用的是其中的etree物件(lxml庫需保持在3.8版本以下)
簡單頁面解析
import requests
from lxml import etree
res = requests.get('https://www.baidu.com/' ).text
# 使用etree.HTML()完成標籤優化,準備解析
html = etree.HTML(res)
print(html.xpath('string(//*[@id="u1"]/a[@name="tj_trtieba"]/@href)'))
頁面內容抓取
import requests
from lxml import etree
from urllib.parse import urljoin
# 本例實際使用requests+lxml來抓取python百例資訊
url = 'http://www.runoob.com/python/python-100-examples.html'
res = requests.get(url).text
html = etree.HTML(res)
li_list = html.xpath('//*[@id="content"]/ul/li')
exam_list = []
for li in li_list:
href = li.xpath('a/@href')
exam_url = urljoin(url, href[0])
# 此處使用requests預設解析會亂碼,需要抓取正文手動解碼
exam_res = requests.get(exam_url).content.decode('utf-8')
exam_html = etree.HTML(exam_res)
title = exam_html.xpath('string(//*[@id="content"]/h1)')
quest = exam_html.xpath('string(//*[@id="content"]/p[2])')
analyse = exam_html.xpath('string(//*[@id="content"]/p[3])')
code = exam_html.xpath('string(//div[@class="hl-main"]|//pre[@class="prettyprint prettyprinted"])')
exam_dict = {
'title': title,
'quest': quest,
'analyse': analyse,
'code': code
}
print(exam_dict)
exam_list.append(exam_dict)
import pandas
df = pandas.DataFrame(exam_list, columns=['title', 'quest', 'analyse', 'code'])
df.to_csv('exam.csv')