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