xpath解析是我们最经常应用的数据解析方式,我们今天就来介绍xpath解析。
xpath解析
进行xpath解析大致分为以下几个步骤:
1.导入lxml库,导入etree模块
2.实例化etree对象tree
3.数据解析
4.保存爬取到的数据
1.引入etree模块
在这里,我学习的视频里面导入etree模块是直接从lxml库中导入的,但是好像py3以后就不能直接从lxml库中导入etree了,需要先从lxml中导入html库,利用html导入etree具体代码如下:
from lxml import html
etree=html.etree
经过这两个步骤我们就获取了etree模块了。
2.实例化etree对象
实例化etree对象时和我们实例化bs4对象相似,有两种方式可以选择。
一种是从本地文件中直接加载,一种是从页面响应内容中加载。
2.1从本地html加载etree对象
将本地文件的路径传入到etree的HTML方法中即可代码如下
from lxml import html
etree=html.etree
#调用etree模块的HTML方法将本地html路径当作参数传入
tree=etree.HTML('页面02.html')
print("加载成功!内容是:"+str(tree[0]))
ps(我之前加载本地html的时候报了一个异常,忘记具体是什么内容了,说的应该是解析器问题,然后用下面的代码就可以解决,如果你没有出现这个问题请忽略这段文字)
from lxml import html
etree=html.etree
parser = etree.HTMLParser(encoding="utf-8")
tree=etree.parse('页面02.html',parser=parser)
print("加载成功!"+str(tree))
2.2从页面响应中加载etree对象
主要有以下三个步骤
1.发送请求
2.获取响应对象
3.将响应对象当作参数传入HTML方法
具体代码如下
from lxml import html
import requests
etree=html.etree
#目标页面的url
url='https://www.csdn.net/'
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36 Edg/89.0.774.77'
}
#用requests库发送请求,对请求结果调用content属性获取相应内容
page_content=requests.get(url=url,headers=headers).content
#将响应内容传入HTML方法中
tree=etree.HTML(page_content)
print("加载成功!"+str(tree[0]))
3.利用xpath进行数据解析
我们获取tree对象后就可以利用tree对象的方法和属性进行数据解析了。
进行数据解析的时候我们只需要把编写的xpath表达式放入tree对象的xpath方法中就可以获取一个满足xpath表达式要求的对象列表,后续对这个列表进行操作即可。所以我们进行数据解析的关键是编写xpath表达式,那么什么是xpath表达式呢?
xpath表达式
xpath我个人的理解就是根据页面的标签编写的表达式用于获取页面标签里的数据。
1.标签定位
比如我们想要获取这张页面百度一下这四个字,我们通过抓包工具进行分析可以找到这个提交框对应的代码所在位置。
然后我们根据层级关系依次找到所需要的标签所对应的上级标签。如下图所示
我们分析发现
img的最外层标签是class值为’s_form s_form_login’的div标签,再下级是class值为’s_form_wrapper soutu-env-nomac soutu-env-newindex c-wrapper c-wrapper-l’的div标签,第三层是name为’f’的form标签,第四层是class值为’btn_wr s_btn_wr bg’的span标签,最里面是我们的input标签。
我们分析出了’百度一下’这四个字所在的标签,那么我们就可以编写xpath表达式来获取这个标签:
1.标签定位
1.xpath表达式中用’/'来表示层级关系,标签名+/表示跳过这个标签的层级
2.用‘//’表示跳跃多个层级
所以我们的xpath表达式可以写为:
1.xpath01='//input[@type="submit"]' #用//跳跃多个层级
这种直接跳跃多个层级的用的比较多,不用一层一层分析比较便捷。
如果我们要定位属性名为A,属性值为B的标签X则应该这样书写:
xpath01=’//X[@cA(属性名)=B(属性值)]
2.属性定位
我们需要的是input标签中属性value的值,所以我们在input标签后面使用/@value获取value的属性值
代码如下:
tree=etree.HTML(page_content)
xpath01='//input[@type="submit"]/@value'
content01=tree.xpath(xpath01)
print(content01[0])
注意我们输出的时候由于获取的符合要求的内容被存放在了一个列表中,所以实际上我们输出的是一个列表,这时候我们一般采用字符串下标获取的方式获取里面的文本内容content01[0]表示获取content01列表中第一个内容。
3.获取文本内容
采用/text()或//text()来获取文本内容,/text()获取直系文本,//text()获取这段标签的所有文本。
最后将我学习xpath的时候的笔记奉上供大家参考补充
step02
编写xpath表达式
xpath('xpath表达式')
step03xpath表达式
01标签定位:
1.'/html/body/div':表示从根节点开始寻找,标签与标签之间的/表示一个层级,最开始的/表示从根节点开始寻找,类似于select的>
2.'/html//div'://表示多个层级,作用于两个标签之间,开始的/表示从根节点开始寻找类似于select方法中的空格
3.'//div':表示从任意节点寻找div标签,即寻找所有的div
4. ./表示从当前标签开始寻找
02属性定位:
1.要定位div中属性为class,值为x的div标签:@属性名=属性值
'/html/body/div[@class="x"]',其中class为属性名,x为属性值
03索引定位:
在class值为x的div标签下有许多p标签,想要定位到第三个p标签:后面跟个中括号加索引位置(注意索引位置从1开始)
'/html/body/div[@class="x"]/p[3]'
step04
01.取文本:/text():获取标签中直系文本
//text():获取标签中所有的文本
他们的返回值都是列表类型,取字符串的话用[位置]即可
02.取属性:/@属性名
note03
如果编写xpath表达式时,所要爬取的目标处在不同的层级:
例如:目标1:/div[@class='we']/ul/li
目标2:/div/ul/div[@class='yu']/ul/li
则可以用逻辑或|将两个表达式连在一起:xpath('/div[@class='we']/ul/li'|'/div/ul/div[@class='yu']/ul/li')
学习了xpath后我们就可以进行基本的网页的爬取了,大家可以先尝试一下爬取某荣耀的英雄列表,今天就到这里啦下次见咯!
某荣耀爬取代码传送门