python 爬取数据计算,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

测试文本:

you

me

he

有用

没用

完善

>

练习代码:

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同城房源的标题

a8597ebb5f4eabfe4d59ea82f713cea8.png

通过分析会发现这样的层级关系,各个房源的信息标题都存在这个层级之中

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

标签而如果使用

//

的话就又从跟目录解析了

爬取成功

6b12d0e80d4d056a9ca1ecd86ebcde0b.png

0x02:爬取4K超清壁纸

57d2b3e4ce8e1f739818320a6242ee73.png

利用Xpath来爬取4K超强壁纸,首先还是需要分析一下:

18b3ededc428b5f9f75b5375089ebfa2.png

我们需要爬取是图片的链接和名称,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)

这样就可以得到图片的链接和名称了,但是出现了一个问题

93f9f71dbc309eb031a86e4c4cecca28.png

名称发生了乱码,这里就需要自己手动设置响应数据的编码格式了

repose = requests.get(url=url,headers=headers)

#手动进行设置响应数据的编码格式

repose.encoding = 'gbk'

page_txt = repose.text

这是第一种方法,对整体的响应数据设置特定的编码格式

65cf3e93d1f625cff0a4992fdf40c54b.png

#通用处理中文乱码的解决方法

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,"下载成功")

爬取成功

365dd9f001ad756932039250300e954a.png

0b55049a9a26a6311cfe8c1ff950a957.png

(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:爬取各个城市的空气质量

3c515e94a0fbfe45c3b39190f0a85ac5.png

分析和之前一样,就不再叙述

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!')

爬取成功

6759aa315014474949db9a388fc00659.png

总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值