语法规则
XPath
使用路径表达式来选取文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
表达式 | 描述 |
| 选中该元素 |
| 从根节点选取、或者是元素和元素间的过渡 |
| 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
| 选取当前节点 |
| 选取当前节点的父节点 |
| 选取属性 |
| 选取文本 |
路径表达式
路径表达式 | 结果 |
| 选择bookstore元素 |
| 选取根元素 bookstore。注释:假如路径起始于正斜杠( |
| 选取属于 bookstore 的子元素的所有 book 元素 |
| 选取所有 book 子元素,而不管它们在文档中的位置 |
| 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置 |
| 选择所有的book下面的title中的lang属性的值 |
| 选择所有的book下面的title的文本 |
查询特定节点
路径表达式 | 结果 |
| 选择lang属性值为eng的所有title元素 |
| 选取属于 bookstore 子元素的第1个 book 元素 |
| 选取属于 bookstore 子元素的最后1个 book 元素 |
| 选取属于 bookstore 子元素的倒数第2个 book 元素 |
| 选择bookstore下面的book元素,从第2个开始选择 |
| 选择bookstore下面的book元素,从第2个开始取到第4个元素 |
| 选择所有book下的title元素,仅仅选择文本为Harry Potter的title元素 |
注意点: 在XPath
中,第一个元素的位置是1
,最后一个元素的位置是last()
,倒数第二个是last()-1
语法练习
接下来对豆瓣电影top250的页面来练习上述语法:豆瓣电影 Top 250
- 选择所有的
h1
下的文本
//h1/text()
- 获取电影信息的
href
属性
//div[@class='item']//div[@class='hd']/a/@href
- 获取电影的评价人数
//div[@class='star']/span[last()]/text()
总结
XPath
的概述:XPath (XML Path Language)
,解析查找提取信息的语言xml
是和服务器交互的数据格式和json
的作用一致html
是浏览器解析标签数据显示给用户XPath
的重点语法获取任意节点://
XPath
的重点语法根据属性获取节点:标签[@属性 = '值']
XPath
的获取节点属性值:@属性值
XPath
的获取节点文本值:text()
案例-抓取豆瓣电影信息
import requests
# import lxml.html as lh
from lxml import etree
import chardet
from multiprocessing.dummy import Pool
times=input('输入抓取页面数:')
startUrl='https://movie.douban.com/top250?start='
urls=[]
for page in range(int(times)):
urls.append(startUrl+str(25*page))
#获取网页源代码
def getHtml(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36 Edg/103.0.1264.622"
}
# requests.get(url)获取响应,.content获取网页二进制编码内容
html_b = requests.get(url,headers=headers).content
# chardet.detect(html_b)#检测二进制代码的编码方式
# print(chardet.detect(html_b))
html = html_b.decode()
return html
html=getHtml(startUrl)
# print(html)
# 多线程访问多个页面
pool=Pool(5)
htmls=pool.map(getHtml,urls)
pool.close()
pool.join()
# 抓取页面信息
def XpathGetInfo(html):
html_xpath=etree.HTML(html)#将html页面转换为xpath结构
data=html_xpath.xpath('//ol[@class="grid_view"]/li')
results=[]
# 获取一页的电影信息
for i in range(len(data)):
res = {}
info=data[i].xpath('.//div[@class="hd"]')
# print(blockInfo)
# 获取电影链接
href=info[0].xpath('.//a/@href')[0]
# 获取电影名称
name=info[0].xpath('.//a/span[@class="title"]/text()')[0]
starInfo=data[i].xpath('.//div[@class="bd"]')
star=starInfo[0].xpath('.//span[@class="rating_num" and @property="v:average"]/text()')[0]
res['name']=name
res['href']=href
res['star']=star
results.append(res)
return results
pool=Pool(5)
res=pool.map(XpathGetInfo,htmls)
#抓取times页电影信息
for i in range(int(times)):
print(res[i])