Python XPath解析器的使用

(一)XPath基础知识

XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。

W3School官方文档:http://www.w3school.com.cn/xpath/index.asp

1.XPath如何解析HTML文本内容?

我们可以 将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素。

2.XPath 开发工具
  1. 开源的XPath表达式编辑工具:XMLQuire(XML格式文件可用)
  2. Chrome插件 XPath Helper
  3. Firefox插件 XPath Checker
3.XPath的基本语法
表达式描述实例
//node_name匹配所有node_name节点//div(获取所有div元素)
/node_name选择当前元素//div/ul(选择所有div内的ul对象)
@attr选择一个元素的属性//div/ul/@class(选择ul元素class属性值)
[@attr=“attr_value”]选择特定属性值的元素//div[@id=“hello”] (选择id为hello的div)
text()从根节点或元素中选择文本//div[@id=“hello”]/ul/li/text()(选择id为“hello”的div中的列表中li的文本内容)
contains(@attr,“value”)模糊匹配div[contains(@id,“he”)](选择id属性包含"he"的div)
*通配符//div/ul/li
[1,2…]或[first()]或[last()]根据节点出现的顺序选择元素//div/ul/li[3](选择所有div中ul中的第三个列表对象 )
4.实例演示

xml文本内容为:

<?xml version="1.0" encoding="utf-8"?>
<bookstore> 
 <book category="cooking"> 
    <title lang="en">湘菜系列</title>  
    <author>王大厨</author>  
    <year>2018</year>  
    <price>38.00</price> 
  </book>  

  <book category="children"> 
    <title lang="ok">猫和老鼠</title>  
    <author>张三</author>  
    <year>2011</year>  
    <price>29.99</price> 
  </book>  

  <book category="web"> 
    <title lang="en">前端基础</title>  
    <author>张三</author>  
    <author>李四</author>  
    <year>2013</year>  
    <price>49.99</price> 
  </book> 

  <book category="web前端" cover="paperback"> 
    <title lang="en">XML基础</title>  
    <author>张亮</author>  
    <year>2015</year>  
    <price>39.95</price> 
  </book> 

</bookstore>

注意:

1.解析xml的方式:
from lxml import etree
#创建ElementTree对象解析xml文本
tree= etree.parse('test.xml')

2.解析html的方式:
from lxml import etree
#创建ElementTree对象解析xml文本
tree= etree.HTML('test.html')

1.使用表达式//node_name可以定位到任何元素,比如定位到title元素。

from lxml import etree
#1.创建ElementTree对象解析xml文本
tree= etree.parse('test.xml')
print(type(tree))

#2.定位到title元素
tags=tree.xpath('//title')
for tag in tags:
    print(tag)

2.使用/node_name定位到某个元素,一般和//node_name结合使用。如果和/node_name结合使用一定得从根节点开始,否则匹配不到元素。

 方式一:
 elements=tree.xpath('//book/title')
 方式二:
 elements=tree.xpath('/bookstore/book/title')

3.使用@atrr获取某一个元素属性的值

elements=tree.xpath('/bookstore/book/@category')

4.使用[@attr=“attr_value”]获取某一个具体元素。比如获取属性category=“web”的div元素。

elements=tree.xpath('//book[@category="web"]')

5.使用text()获取title元素的内容

elements=tree.xpath('//book/title/text()')

6.使用contains(@attr,“value”) 匹配category="we"的div元素

elements=tree.xpath('//book[contains(@category,"we")]')

7.使用*通配符匹配所有后继元素,比如匹配book元素的后继元素

elements=tree.xpath('//book/*')

8.使用first()或last()或[1,2,3…]匹配某个元素。比如匹配第二个book元素。

elements=tree.xpath('//book[2]')

elements=tree.xpath('//book[last()]')
(二)获取天猫商城nike男鞋的评价数据
1.使用以下工具:
  1. requests模块
  2. lxml库中的etree模块
2.获取数据的基本思路
  1. 使用requests模块中的get()方法向服务器发送get请求
  2. 使用response对象获取HTML文本
  3. 使用XPath语法解析HTML文本获取数据
  4. 将解析得到的数据保存到csv、json文本或数据库。
3.获取分页内容是解析所有网页的关键

如图所示
这里写图片描述

注意: url中s的值的变化成等差数列

代码如下:

from requests import get
from lxml import etree
 

#1.定义一个列表保存评价数据
list_pj=[]
#2.获取HTML文本
def getDatas():
    headers={"user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
    for i in range(1,101):
       print("----以下为第"+str(i)+"页----")
       url="https://list.tmall.com/search_product.htm?q=nike 男鞋&s="+str(60*(i-1))
       response=get(url,headers=headers) 
       parseHtml(response.text)
        
   

#3.解析HTML文本内容,获取目标数据
def parseHtml(html):
     selector=etree.HTML(html)
     evaluations=selector.xpath('//div[@class="product-iWrap"]/p[@class="productStatus"]/span[2]/a/text()')
     
     #遍历
     for evaluation in  evaluations:
         list_pj.append(evaluation)
         print("评价人数为:"+evaluation)
         

html=getDatas() 

 
#定义一个字典保存数据
dict1={}
dict1["one"]=list_pj
dict1["two"]=list_pj
dict1["three"]=list_pj
dict1["four"]=list_pj

#4.将数据保存文json格式文本中
with open("D:\helloo.json",'w') as f:
    f.write(str(dict1))

(三)获取猫眼电影Top100榜单数据并写入csv文件
1.使用工具
  • requests模块
  • lxml库
  • csv模块

2.源码演示
import requests
from urllib.error import HTTPError,URLError
from lxml import etree
import csv
class Spider():
    def __init__(self):
        self.rankings=[]
        self.movie_names=[]
        self.main_stars=[]
        self.release_dates=[]
        self.evaluations=[]

    def getHtml(self,url):
        headers = {"User-Agent": "Mozilla/5.0"}
        try:
            response = requests.get(url, headers=headers)
        except(HTTPError,URLError) as e:
            return None
        return response.text

    #1.获取排名
    def getRanking(self,html):
        tree = etree.HTML(html)
        ranks= tree.xpath('//div[@class="main"]/dl[@class="board-wrapper"]/dd/i/text()')
        for rank in ranks:
            self.rankings.append(rank)
        return self.rankings

    #2.获取电影名
    def getMovie(self,html):
        tree = etree.HTML(html)
        movies= tree.xpath('//p[@class="name"]/a/text()')
        for movie in movies:
            self.movie_names.append(movie)
        return self.movie_names

    #3.获取主演
    def getStars(self,html):
        tree = etree.HTML(html)
        stars= tree.xpath('//p[@class="star"]/text()')
        for star in stars:
            self.main_stars.append(star.replace('\n','').strip(' ')[3:])
        return self.main_stars
    #4.获取上映时间
    def getReleasetime(self,html):
        tree = etree.HTML(html)
        dates = tree.xpath('//p[@class="releasetime"]/text()')
        for date in dates:
            self.release_dates.append(date[5:])
        return self.release_dates

    #5.获取评分
    def getEvaluations(self,html):
        tree = etree.HTML(html)
        evaluation_integer=[]
        evaluations_fraction=[]
        evaluation_i=tree.xpath('//i[@class="integer"]/text()')
        evaluation_f=tree.xpath('//i[@class="fraction"]/text()')
        for i in range(len(evaluation_i)):
            total=evaluation_i[i]+evaluation_f[i]
            self.evaluations.append(total)
        return self.evaluations

if __name__ == '__main__':
    spider = Spider()
    rankings=[]
    movie_names=[]
    main_stars=[]
    release_dates=[]
    evaluations=[]
    for i in range(10):
        url = "http://maoyan.com/board/4?offset="+str(i*10)
        html=spider.getHtml(url)
        if html!=None:
            rankings = spider.getRanking(html)
            movie_names = spider.getMovie(html)
            main_stars = spider.getStars(html)
            release_dates = spider.getReleasetime(html)
            evaluations = spider.getEvaluations(html)

    with open("D:\spider.csv", "w", newline='', encoding='utf-8')as f:
        write = csv.writer(f)
        write.writerow(('排名', '电影名', '主演', '上映时间', '评分'))
        for i in range(len(rankings)):
            write.writerow([rankings[i], movie_names[i], main_stars[i], release_dates[i], evaluations[i]])
    print('数据写入完毕!')




结果演示:
这里写图片描述


(四)获取豆瓣图书Top250

源码演示:

from lxml import etree
import requests
import time
count=0
d=0

#1.获取前10页豆瓣读书
for a in range(10):
    url = 'https://book.douban.com/top250?start={}'.format(a*25)
    data = requests.get(url).text

    s=etree.HTML(data)
    tags=s.xpath('//*[@id="content"]/div/div[1]/div/table')
    time.sleep(3)

    for div in tags:
        title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]
        href = div.xpath("./tr/td[2]/div[1]/a/@href")[0]
        score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]
        num=div.xpath("./tr/td[2]/div[2]/span[3]/text()")[0].strip("(").strip().strip(")").strip()
        scrible=div.xpath("./tr/td[2]/p[2]/span/text()")

        if len(scrible) > 0:
           count+=1
           print("{},{},{},{},{}\n".format(title,href,score,num,scrible[0]))
        else:
            d+=1
            print("{},{},{},{}\n".format(title,href,score,num))
print("有评价的书总数======="+str(count))
print("未评价的书总数======="+str(d))
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值