中国河北建设银行官网招聘网站,网站建设与功能模块,台州易搜网络科技有限公司,seo营销培训咨询一、前言
前两篇博客讲解了爬虫解析网页数据的两种常用方法#xff0c;re正则表达解析和beautifulsoup标签解析#xff0c;所以今天的博客将围绕另外一种数据解析方法#xff0c;它就是xpath模块解析#xff0c;话不多说#xff0c;进入内容#xff1a;
一、简介
XPat…一、前言
前两篇博客讲解了爬虫解析网页数据的两种常用方法re正则表达解析和beautifulsoup标签解析所以今天的博客将围绕另外一种数据解析方法它就是xpath模块解析话不多说进入内容
一、简介
XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素并且 XQuery 和 XPointer 都构建于 XPath 表达之上。
XPath即为XML路径语言XML Path Language它是一种用来确定XML文档中某部分位置的语言。
xpath是最常用且最便捷高效的一种解析方式通用型强其不仅可以用于python语言中还可以用于其他语言中数据解析建议首先xpath。
二、安装
pip3 install lxml
三、使用
1、导入
from lxml import etree
2、基本使用
实例化一个etree的对象且需要将被解析的页面源代码数据加载到该对象中
调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕获
from lxml import etree
tree etree.parse(./tree.html) #从本地加载源码实例化一个etree对象。必须是本地的文件不能是字符串
tree etree.HTML(源码) #从互联网加载源码实例化etree对象
# / 表示从从根节点开始一个 / 表示一个层级//表示多个层级
r tree.xpath(//div//a) #以列表的形式返回div下的所有的a标签对象的地址
r tree.xpath(//div//a)[1] #返回div下的第二个a标签对象地址
r tree.xpath(//div[classtang]) #以列表的形式返回tang标签地址
r tree.xpath(//div[classtang]//a) #以列表的形式返回tang标签下所有的a标签地址
#获取标签中的文本内容
r tree.xpath(//div[classtang]//a/text()) #以列表的形式返回所有a标签中的文本
#获取标签中属性值
r tree.xpath(//div//a/href) ##以列表的形式返回所有a标签中href属性值
3、基本使用
from lxml import etreewb_data divullia hreflink1.htmlfirst item/a/lilia hreflink2.htmlsecond item/a/lilia hreflink3.htmlthird item/a/lilia hreflink4.htmlfourth item/a/lilia hreflink5.htmlfifth item/a/ul/div
html etree.HTML(wb_data)
print(html)
result etree.tostring(html)
print(result.decode(utf-8))
从下面的结果来看我们打印机html其实就是一个python对象etree.tostring(html)则是补全html的基本写法补全了缺胳膊少腿的标签。
Element html at 0x39e58f0
htmlbodydivullia hreflink1.htmlfirst item/a/lilia hreflink2.htmlsecond item/a/lilia hreflink3.htmlthird item/a/lilia hreflink4.htmlfourth item/a/lilia hreflink5.htmlfifth item/a/li/ul/div/body/html
3、获取某个标签的内容(基本使用)注意获取a标签的所有内容a后面就不用再加正斜杠否则报错。
写法一
html etree.HTML(wb_data)
html_data html.xpath(/html/body/div/ul/li/a)
print(html)
for i in html_data:print(i.text)# 打印结果如下
Element html at 0x12fe4b8
first item
second item
third item
fourth item
fifth item
写法二直接在需要查找内容的标签后面加一个/text()就行
html etree.HTML(wb_data)
html_data html.xpath(/html/body/div/ul/li/a/text())
print(html)
for i in html_data:print(i)# 打印结果如下
Element html at 0x138e4b8
first item
second item
third item
fourth item
fifth item
4、打开读取html文件
#使用parse打开html的文件
html etree.parse(test.html)
html_data html.xpath(//*)br#打印是一个列表需要遍历
print(html_data)
for i in html_data:print(i.text) html etree.parse(test.html)
html_data etree.tostring(html,pretty_printTrue)
res html_data.decode(utf-8)
print(res)打印
divullia hreflink1.htmlfirst item/a/lilia hreflink2.htmlsecond item/a/lilia hreflink3.htmlthird item/a/lilia hreflink4.htmlfourth item/a/lilia hreflink5.htmlfifth item/a/li/ul
/div 5、打印指定路径下a标签的属性可以通过遍历拿到某个属性的值查找标签的内容 html etree.HTML(wb_data)
html_data html.xpath(/html/body/div/ul/li/a/href)
for i in html_data:print(i)打印
link1.html
link2.html
link3.html
link4.html
link5.html 6、我们知道我们使用xpath拿到得都是一个个的ElementTree对象所以如果需要查找内容的话还需要遍历拿到数据的列表。
查到绝对路径下a标签属性等于link2.html的内容。 html etree.HTML(wb_data)
html_data html.xpath(/html/body/div/ul/li/a[hreflink2.html]/text())
print(html_data)
for i in html_data:print(i)打印
[second item]
second item 7、上面我们找到全部都是绝对路径每一个都是从根开始查找下面我们查找相对路径例如查找所有li标签下的a标签内容。 html etree.HTML(wb_data)
html_data html.xpath(//li/a/text())
print(html_data)
for i in html_data:print(i)打印
[first item, second item, third item, fourth item, fifth item]
first item
second item
third item
fourth item
fifth item 8、上面我们使用绝对路径查找了所有a标签的属性等于href属性值利用的是/—绝对路径下面我们使用相对路径查找一下l相对路径下li标签下的a标签下的href属性的值注意a标签后面需要双//。 html etree.HTML(wb_data)
html_data html.xpath(//li/a//href)
print(html_data)
for i in html_data:print(i)打印
[link1.html, link2.html, link3.html, link4.html, link5.html]
link1.html
link2.html
link3.html
link4.html
link5.html 9、相对路径下跟绝对路径下查特定属性的方法类似也可以说相同。 html etree.HTML(wb_data)
html_data html.xpath(//li/a[hreflink2.html])
print(html_data)
for i in html_data:print(i.text)打印
[Element a at 0x216e468]
second item 10、查找最后一个li标签里的a标签的href属性 html etree.HTML(wb_data)
html_data html.xpath(//li[last()]/a/text())
print(html_data)
for i in html_data:print(i)打印
[fifth item]
fifth item 11、查找倒数第二个li标签里的a标签的href属性 html etree.HTML(wb_data)
html_data html.xpath(//li[last()-1]/a/text())
print(html_data)
for i in html_data:print(i)打印
[fourth item]
fourth item 四、案例
案例1获取58商城房价单位
import requests
from lxml import etree
url https://bj.58.com/ershoufang/p1/
headers{User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Mobile Safari/537.36
}
pag_response requests.get(url,headersheaders,timeout3).text
#实例化一个etree对象
tree etree.HTML(pag_response)
r tree.xpath(//span[classcontent-title]/text()) #获取所有//span标签为content-title的文本内容,列表形式
with open(58房价.txt,modew,encodingutf-8) as fp:for r_list in r:fp.writelines(str(r_list))print(r_list)案例2获取豆瓣top榜电影信息这个是老生常谈的话题了 import re
from time import sleep
import requests
from lxml import etree
import random
import csvdef main(page,f):url fhttps://movie.douban.com/top250?start{page*25}filterheaders {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.35 Safari/537.36,}resp requests.get(url,headersheaders)tree etree.HTML(resp.text)# 获取详情页的链接列表href_list tree.xpath(//*[idcontent]/div/div[1]/ol/li/div/div[1]/a/href)# 获取电影名称列表name_list tree.xpath(//*[idcontent]/div/div[1]/ol/li/div/div[2]/div[1]/a/span[1]/text())for url,name in zip(href_list,name_list):f.flush() # 刷新文件try:get_info(url,name) # 获取详情页的信息except:passsleep(1 random.random()) # 休息print(f第{i1}页爬取完毕)def get_info(url,name):headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.35 Safari/537.36,Host: movie.douban.com,}resp requests.get(url,headersheaders)html resp.texttree etree.HTML(html)# 导演dir tree.xpath(//*[idinfo]/span[1]/span[2]/a/text())[0]# 电影类型type_ re.findall(rpropertyv:genre(.*?)/span,html)type_ /.join(type_)# 国家country re.findall(r地区:/span (.*?)br,html)[0]# 上映时间time tree.xpath(//*[idcontent]/h1/span[2]/text())[0]time time[1:5]# 评分rate tree.xpath(//*[idinterest_sectl]/div[1]/div[2]/strong/text())[0]# 评论人数people tree.xpath(//*[idinterest_sectl]/div[1]/div[2]/div/div[2]/a/span/text())[0]print(name,dir,type_,country,time,rate,people) # 打印结果csvwriter.writerow((name,dir,type_,country,time,rate,people)) # 保存到文件中if __name__ __main__:# 创建文件用于保存数据with open(03-movie-xpath.csv,a,encodingutf-8,newline)as f:csvwriter csv.writer(f)# 写入表头标题csvwriter.writerow((电影名称,导演,电影类型,国家,上映年份,评分,评论人数))for i in range(10): # 爬取10页main(i,f) # 调用主函数sleep(3 random.random())