Python爬虫之旅_(数据解析)_Xpath

前言:

上次学习过了BeautifulSoup进行解析的,这次就来学习一下Xpath进行解析

0x00:了解Xpath

Xpath解析:最常用且最高效的一种解析方式

Xpath解析原理:
	——1.实例化一个etree对象,且需要将解析的页面源码数据加载到该数据中。
	——2.调用etree对象中的xpath方法结合xpath表达式实现标签的定位和内容的捕获
如何实例化一个etree对象
	——1.将本地的html文档中的源码数据加载到etree对象中:
		etree.parse(filePath)
	——2.可以将从互联网上获取的源码数据加载到该对象中:
		etree.HTML('page_text')
	——xpath('xpath表达式')
xpath表达式
	—— /:表示的是从根节点开始定位,表示的是一个层级。
	—— // :
	表示的是多个层级,可以从任意位置开始定位
	—— 属性定位: 
	//div[@class='dingpai']
	tag[@attrName="attrValue"]
	——索引定位:
	//div[@class="dingpai"]/p[3] 索引是从1开始的
	——取文本:
		—— /test() 获取的是标签中直系的文本内容
		—— //test() 
	——取属性:
		/@attrName
		//div[@class="dingpai"]//a[1]/@href

测试文本:

<html lang="en">
<body>
<div class="dingpai">
<p>you</p>
<p>me</p>
<p>he</p>
<li>
<a id="ding79" href="javascript:ding('79','http://so.gushiwen.org/shiwenv.aspx?id=8dd719a833f0')">有用</a>
<a id="pai79" style=" margin-left:10px;" href="javascript:pai('79','http://so.gushiwen.org/shiwenv.aspx?id=8dd719a833f0')">没用</a>
<a style="width:34px; height:18px; line-height:19px; margin-top:2px; float:right; color:#aeaeae;" href="/jiucuo.aspx?u=%e7%bf%bb%e8%af%9179%e3%80%8a%e8%af%91%e6%96%87%e5%8f%8a%e6%b3%a8%e9%87%8a%e3%80%8b" target="_blank">完善</a>
</li>
</div>
</body>>
</html>

练习代码:

import requests
from lxml import etree
if __name__ == '__main__':
    #实例化一个etree对象,且将被解析的源码加载到该对象中
    tree = etree.parse('test.html')
    # r = tree.xpath('/html/div/li')
    # r = tree.xpath('/html//li')
    # r = tree.xpath('//li')
    # r = tree.xpath('//div[@class="dingpai"]')
    # r = tree.xpath('//div[@class="dingpai"]/p[3]')
    #加[0]是为了得到字符串
    # r = tree.xpath('//div[@class="dingpai"]/li/a[3]/text()')[0]
    # r = tree.xpath('//a[3]//text()')
    # r = tree.xpath('//div[@class="dingpai"]//a[1]/@href')[0]
    print(r)

0x01:爬取58二手房房源信息

这次就使用Xpath来爬取一下58同城房源的标题
在这里插入图片描述
通过分析会发现这样的层级关系,各个房源的信息标题都存在这个层级之中
ul class="house-list-wrap">li>div class="list-info">h2 class="title">a
分析好之后,便可以使用xpath来进行解析

import requests
from lxml import etree

if __name__ == '__main__':
    url = 'https://jiaozuo.58.com/ershoufang/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }
    content = requests.get(url=url,headers=headers).text
    #数据解析
    tree = etree.HTML(content)
    #存储的是li标签的对象
    li_list = tree.xpath('//ul[@class="house-list-wrap"]/li')
    fp = open('58.txt','w',encoding='utf-8')
    for li in li_list:
        #从li标签开始调用
        #./表示的是局部的li标签,直接定位到局部
        title = li.xpath('./div[2]/h2/a/text()')[0]
        # print(title)
        price = li.xpath('./div[3]/p/b/text()')[0]
        print(price+"万")
        fp.write(title+price+'万'+'\n')

这样最需要注意的便是这个./,这个可以直接定位到当前的li标签而如果使用//的话就又从跟目录解析了

爬取成功
在这里插入图片描述

0x02:爬取4K超清壁纸

在这里插入图片描述
利用Xpath来爬取4K超强壁纸,首先还是需要分析一下:
在这里插入图片描述
我们需要爬取是图片的链接和名称,F12可以看到层级关系是这样的

div class="slist" >ul>li>a

分析一个其他用循环即可,下面就来写出爬取脚本:

import requests
from lxml import etree

if __name__ == '__main__':
    url = 'http://pic.netbian.com/4kdongman/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }
    repose = requests.get(url=url,headers=headers).text
    #进行实例化
    tree = etree.HTML(repose)
    #得到所有的li列表
    li_list = tree.xpath('//div[@class="slist"]/ul/li')
    for li in li_list:
        #得到图片的url,但这里不是完整的,所以需要拼接一下
        img_url = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0]
        #得到图片的名称
        imge_name = li.xpath('./a/img/@alt')[0]+'.jpg'
        print(imge_name+':'+img_url)

这样就可以得到图片的链接和名称了,但是出现了一个问题
在这里插入图片描述
名称发生了乱码,这里就需要自己手动设置响应数据的编码格式了

 repose = requests.get(url=url,headers=headers)
    #手动进行设置响应数据的编码格式
    repose.encoding = 'gbk'
    page_txt = repose.text

这是第一种方法,对整体的响应数据设置特定的编码格式
在这里插入图片描述

#通用处理中文乱码的解决方法
image_name = imge_name.encode('iso-8859-1').decode('gbk')

接下来就只需请求图片的url,进行爬取即可

import requests
from lxml import etree
import os
if __name__ == '__main__':
    url = 'http://pic.netbian.com/4kdongman/'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }
    repose = requests.get(url=url,headers=headers)
    #手动进行设置响应数据的编码格式
    repose.encoding = 'gbk'
    page_text = repose.text
    #进行实例化
    tree = etree.HTML(page_text)
    #得到所有的li列表
    li_list = tree.xpath('//div[@class="slist"]/ul/li')
    #创建一个文件夹
    if not os.path.exists('pic'):
        os.mkdir('pic')
    for li in li_list:
        #得到图片的url,但这里不是完整的,所以需要拼接一下
        img_url = 'http://pic.netbian.com'+li.xpath('./a/img/@src')[0]
        #得到图片的名称
        imge_name = li.xpath('./a/img/@alt')[0]+'.jpg'
        #通用处理中文乱码的解决方法
        # image_name = imge_name.encode('iso-8859-1').decode('gbk')
        # print(imge_name,img_url)
        #请求图片,持久化存储.二进制数据用content
        img_data = requests.get(url=img_url,headers=headers).content
        #图片路径
        img_path = 'pic/'+imge_name
        #进行IO操作,将图片存储到文件夹中
        with open(img_path,'wb') as fp:
            fp.write(img_data)
            print(imge_name,"下载成功")

爬取成功
在这里插入图片描述
在这里插入图片描述
(PS:看看就行,分辨率太小)

0x03:使用|运算符获取相同信息

在爬取的过程中就会发现爬取相同的信息(如热门城市和全部城市),但信息分别位于不同的标签中,如果我们使用两个语句去进行解析,在这个过程还要再次循环,效率有点低。遇到这种问题便可以使用如下这种语句

#div/ul/li/a	热门城市a标签的层级关系
#div/ul/div[2]/li/a	全部城市a标签的层级关系
使用一行代码解析全部
tree.xpath('//div/ul/li/a | div/ul/div[2]/li/a')
中间添加一个|运算符进行分割即可获取全部

0x04:爬取各个城市的空气质量

在这里插入图片描述
分析和之前一样,就不再叙述

import requests
from lxml import etree

if __name__ == '__main__':
    url = 'http://www.tianqi.com/air/?o=desc'
    headers = {
        'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
    }
    reponse = requests.get(url=url,headers=headers).text
    #实例化一个对象
    tree= etree.HTML(reponse)
    #解析出所有的li标签列表
    li_list = tree.xpath('//div[@class="wrapbox newsmain"]//ul[@class="aqi_ranklist"]/li')
    fp = open('城市空气质量.txt','w',encoding='utf-8')
    for li in li_list:
        city_sort = li.xpath('./span[1]/text()')[0]
        # print(city_sort)
        city_name = li.xpath('./span/a/text()')[0]
        # print(city_name)
        city_province = li.xpath('./span[3]/text()')[0]
        # print(city_province)
        city_air = li.xpath('./span[4]/text()')[0]
        # print(city_air)
        air_condition = li.xpath('./span[5]/i/text()')[0]
        # print(air_condition)
        fp.write(city_sort+' '+city_name+' '+city_province+' '+city_air+' '+air_condition+'\n')
        print(city_sort+' '+city_name+' '+city_province+' '+city_air+' '+air_condition+'\n')
print('Over!')

爬取成功
在这里插入图片描述

总结

这次就学习到这里,有空继续学习!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值