xpath解析:最常用且最便捷高效的一种解析方式。通用性。
1.实例化一个etree的对象,且需要将被解析的页面源码数据加载到该对象中。
2.调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
pip install lxml
1.将本地的html文档中的源码数据加载到etree对象中:
etree.parse(filrPath)
2.可以将从互联网上获取的源码数据加载到该对象中
etree.HTML('page_text')
xpath('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
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)
如果文字乱码的话:
#方法一
#先获取网页的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,"下载成功!!")
#项目需求:解析出所有城市名称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))
注意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,"下载完成!!!")