2025年3月27日 星期四 甲辰(龙)年 月廿六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

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

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

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,"下载完成!!!")
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门