您当前的位置:首页 > 计算机 > 编程开发 > Python

python爬虫第三章:(三)xpath进行数据解析

时间:11-05来源:作者:点击数:

xpath解析

xpath解析:最常用且最便捷高效的一种解析方式。通用性。

1、xpath解析原理:

1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。

2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。

2、环境的安装:

pip install lxml

3、如何实例化一etree对象:from lxml import entree

  • 1.将本地的html文档中的源码数据加载到etree对象中:

    etree.parse(filrPath)
    
  • 2.可以将从互联网上获取的源码数据加载到该对象中

    etree.HTML('page_text')
    
  • xpath('Xpath表达式') #返回的是列表
    

4.xpath表达式

  • / :表示的是从根节点开始定位。表示的是一个层级。

    例如:test.html中的根节点是html

    #定位到title标签
        r=tree.xpath('/html/head/title')  #从根节点开始一层一层去定位,返回的列表,返回的是element对象,不是具体内容
        print(r)	#输出是列表
        
    '''
    输出:[<Element title at 0x26ed87de2c0>]
    '''
    
    
    #有几个div,返回列表中就有几个Element
        r = tree.xpath('/html/body/div')  # 从根节点开始一层一层去定位,返回的列表,返回的是element对象,不是具体内容
        print(r)
     
    '''
    输出:[<Element div at 0x2041d1ee400>, <Element div at 0x2041d1ee480>, <Element div at 0x2041d1ee4c0>]
    '''
    
  • //:表示的是多个层级。可以表示从任意位置开始定位。

     #有几个div,返回列表中就有几个Element
        r = tree.xpath('//div')  # 同
        print(r)
    
  • 属性定位://div[@class=‘song’] tag[@attrName=“attrValue”]

    div[@class='song'] tag[@attrName="attrValue"]
    
    #例子
    #属性定位
        r = tree.xpath('//div[@class="song"]')   #[]中括号@是固定格式,返回的是列表
    #返回的是[<Element div at 0x2af276df340>]
    
  • 索引定位://div[@class=“song”]/p[3] 索引是从1开始的。

       # 索引定位
        r = tree.xpath('//div[@class="song"]/p[3]')  # []中索引是从1开始的
        print(r)  #[<Element p at 0x29af6930180>]
    
  • 取文本:

    • /text() 获取的是标签中直系的文本内容

      # 定位
          r = tree.xpath('//div[@class="tang"]/ul/li[5]/a/text()')  # []中索引是从1开始的
          print(r)  #['杜牧']
          
          r = tree.xpath('//div[@class="tang"]/ul/li[5]/a/text()')[0] #杜牧
      
    • //text() 标签中非直系的文本内容(所有的文本内容)

      # 取文本  //text()
          r = tree.xpath('//div[@class="tang"]/ul/li[5]//text()')  # []中索引是从1开始的
          print(r)		#['杜牧']
      
      
  • 取属性:
    /@attrName ==>img/src

    # 取属性  /@attrName
        r = tree.xpath('//div[@class="song"]/img/@src')  # @src :@属性  /@attrName
        print(r)  #['http://www.baidu.com/meinv.jpg']
        
         r = tree.xpath('//div[@class="song"]/img/@src')[0] #http://www.baidu.com/meinv.jpg
    

5、xpath实战:58二手房

import requests

from lxml import etree

if __name__=="__main__":

    headers={
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }

    url='https://zz.58.com/ershoufang/'

    page_text=requests.get(url=url,headers=headers).text
    #print(page_text)

    #数据解析
    tree=etree.HTML(page_text)

    #r1与r相同
    
    #r1=tree.xpath('//section[@class="list"]/div/a/div[@class="property-content"]/div[@class="property-content-detail"]/div[@class="property-content-title"]/h3/text()')
    r = tree.xpath('//div[@class="property-content-title"]/h3/text()')

    print(r)
    #print(r1)

6、xpath解析案例-4k图片解析下载

  • 如果文字乱码的话:

    • #方法一
      #先获取网页的HTML
          #page=requests.get(url=url,headers=headers).text        #乱码了
          respone=requests.get(url=url,headers=headers)
          #手动设定解决乱码
          respone.encoding="utf-8"        #乱码没解决
          page=respone.text
      
    • #方法二
         # 通用处理中文乱码的解决方案
              img_name=img_name.encode('iso-8859-1').decode('gbk')
              #print(img_name)
      
      
#需求:解析下载图片数据 http://pic.netbian.com/4kmeinv/
import requests
from lxml import etree
import os

if __name__=="__main__":
    #创建一个新文件夹
    if not os.path.exists('tupian'):
        os.mkdir('tupian')

    headers={
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }
    url='https://pic.netbian.com/4kmeinv/'
    #先获取网页的HTML
    #page=requests.get(url=url,headers=headers).text        #乱码了
    respone=requests.get(url=url,headers=headers)
    #手动设定解决乱码
    #respone.encoding="utf-8"        #乱码没解决
    page=respone.text

    #数据解析
    tree=etree.HTML(page)
    li_list=tree.xpath('//div[@class="slist"]/ul/li')
    #print(li_list)
    for li in li_list:
        img_src='https://pic.netbian.com'+li.xpath('./a/img/@src')[0]
        #print(img_src)
        img_name=li.xpath('./a/img/@alt')[0]+'.jpg'
        # 通用处理中文乱码的解决方案
        img_name=img_name.encode('iso-8859-1').decode('gbk')
        #print(img_name)

        #进行持久化存储
        img_data=requests.get(url=img_src,headers=headers).content #二进制数据
        #图片路径
        img_path='tupian/'+img_name
        with open(img_path,'wb') as fp:
            fp.write(img_data)
            print(img_name,'下载成功!!!')
        # with open(img_path,'wb') as fp:
        #     fp.write(img_data)
        #     print(img_name,"下载成功!!")



7、解析出所有城市名称

#项目需求:解析出所有城市名称https://www.aqistudy.cn/historydata/
import requests
import os
from lxml import etree

if __name__=="__main__":
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }
    url='https://www.aqistudy.cn/historydata/'
    page_text=requests.get(url=url,headers=headers).text

    #数据解析

    tree=etree.HTML(page_text)
    all_city_names = []
    #解析热门
    hot_list=tree.xpath('//div[@class="hot"]/div[@class="bottom"]/ul/li')
    for li in hot_list:
        hot_name=li.xpath('./a/text()')[0]
        all_city_names.append(hot_name)

    name_list=tree.xpath('//div[@class="all"]/div[@class="bottom"]/ul/div[2]/li')
    #host_name_list=tree.xpath('./a/text()')
    #print(name_list)
    #解析所有城市
    for li in name_list:
        host_city_name=li.xpath('./a/text()')[0]
        #print(host_city_name)
        all_city_names.append(host_city_name)

    print(all_city_names,len(all_city_names))


#项目需求:解析出所有城市名称https://www.aqistudy.cn/historydata/
import requests
import os
from lxml import etree
if __name__=="__main__":
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }
    url='https://www.aqistudy.cn/historydata/'
    page_text=requests.get(url=url,headers=headers).text

    #数据解析
    tree = etree.HTML(page_text)

    # 解析到热门城市和所有城市对应的a标签
    # //div[@class="hot"]/div[@class="bottom"]/ul/li         热门城市a标签的层级关系
    # //div[@class="all"]/div[@class="bottom"]/ul/div[2]/li 全部城市a标签的层级关系

    #包括热门城市和全部城市
    a_list=tree.xpath('//div[@class="all"]/div[@class="bottom"]/ul/div[2]/li  | //div[@class="hot"]/div[@class="bottom"]/ul/li  ')
    all_city_names = []
    for a in a_list:
        city_name=a.xpath('./a/text()')[0]
        all_city_names.append(city_name)
    print(all_city_names, len(all_city_names))

8、作业

  • 注意post请求和get请求

  • # 进行持久化存储  二进制数据进行存储
               #data=requests.get(url=page3_url,headers=headers)
    #这里是post请求,get不可以
                data1=requests.post(url=page3_url,headers=headers)
                data2=data1.content
    
#作业:爬取站长素材中免费简历模板 https://sc.chinaz.com/
# https://sc.chinaz.com/jianli/free.html
# 压缩包也是二进制

import requests
from lxml import etree
import os

if __name__=="__main__":
    if not os.path.exists('yasuobao'):
        os.mkdir('yasuobao')

    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }

    url='https://sc.chinaz.com/jianli/free.html'
    page=requests.get(url=url,headers=headers).text

    #解析数据

    tree=etree.HTML(page)
    li_list=tree.xpath('//div[@class="sc_warp  mt20"]/div/div/div')
    #print(li_list)
    for li in li_list:
        post_url='https:'+li.xpath('./a/@href')[0]
        #print(post_url)
        #进入某一简历的网页
        #page1=requests.get(url=post_url,headers=headers).text

        # 手动设定解决乱码
        # response.encoding="utf-8"        #乱码没解决
        response=requests.get(url=post_url,headers=headers)
        response.encoding = "utf-8"
        page1= response.text

        #解析
        tree1=etree.HTML(page1)

        page2=tree1.xpath('//div[@class="down_wrap"]/div[2]/ul/li[1]')

        for lin in page2:
            #提取出压缩包下载链接,不加[0],就在列表
            page3_url=lin.xpath('./a/@href')[0]
            #print(page3_url)
            page3_name=lin.xpath('//div[@class="ppt_tit clearfix"]/h1/text()')[0] +'.rar'
            #文字乱码没有解决,换上一种
            #page3_name = page3_name.encode('iso-8859-1').decode('gbk')
           # print(page3_name)

            # 进行持久化存储  二进制数据进行存储
            #data=requests.get(url=page3_url,headers=headers)

            #这里是post请求,get不可以
            data1=requests.post(url=page3_url,headers=headers)
            data2=data1.content



            #压缩包路径
            page3_path='yasuobao/'+page3_name
            #print(page3_path)
            with open(page3_path,mode='wb') as fp:
                fp.write(data2)
                print(page3_name,"下载完成!!!")
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门