python爬虫:xpath解析

#数据解析中的最后一种方式,xpath是通用性最强的,注意边界高效的一中解析,最好用它来解析。

零、xpath解析原理与准备:

1.标签定位(实例化一个etree的对象,并且需要将被解析的页面源码数据加载到该对象中)

2.通过调用etree对象中的xpath方法结合着xpath表达式实现这个标签的定位和内容的捕获
3.环境的安装

一、如何实例化一个etree对象(两种形式):from lxml import etree

1.将本地的html文档中的源码数据加载到etree对象中:

 etree.parse(filePath)    #本地的文件路径   parse方法

2.可以将从互联网上获取的源码数据加载到该对象中

 etree.HTML('page_text')
           # 这里的etree是一个类,来自于lxml:from lxml import etree
           # 当etree对象实例化好了之后就可以调用这个xpath方法了。

3.重点是xpath表达式的编写————xpath(‘xpath表达式’)

from lxml import etree

if __name__=="__main__":
    tree=etree.parse('test.html') 
    #已经实例化好了一个etree对象,且将被解析的源码加载到了该对象中。

下一步是用xpath方法。

比如说现在想去做标签的定位,这里定位就可以使用xpath表达式定位。
这个表达式可以根据层级关系去实现标签定位,这个层级关系在select方法当中有层级关系,而在xpath就是也只能是根据层级表达式去定位。

tree.xpath('/html/head/title')###表示从html里的head里的title去定位,html前的/表示我们是从根节点,或者说是根目录开始遍历的。
根节点或者根目录,即,在当前源码中,最外层的节点就是根节点,那我们从根节点开始从外到内一层一层定位就可以定位到title。

用r去接收一下xpath:

 #用r去接收一下xpath:
  r=tree.xpath('/html/head/title')
  print(r)

返回的是一个列表,列表当中存储的是一个标签,但是是element列表,这是这个标签被抽象成了element对象了。

还可以:

  r=tree.xpath('/html/body/div')
  print(r)

这个body里有三个div,所以返回的是一个包含三个div的element列表,这三个对象所表示的就是三个div标签。

最左侧的斜杠表示的是从根节点开始做定位,一个斜杠表示的是一个层级
如果:r=tree.xpath('/html//div')   ###运行,更刚刚的运行结果一样,
                        //表示的是多个层级;可以从任意位置开始定位
如果:r=tree.xpath('//div')   ###返回的结果依旧是一样的,这三种表达式含义和作用是一样的,作用到最左侧还是表示从任意位置去定位三个div

(能不能用xpat既能进行属性定位?)
固定格式:属性(clxxx)定位:

      r=tree.xpath('//div[@class="song"]')
      print(r)
      # 运行返回的还是一个列表
      # 结论!!!
      # xpath返回的永远是一个列表把。
      //div[@class='song'] tag[@attrName="attrValue"]

二、获取第三个p标签——所以接下来需要实现索引定位

r=tree.xpath('//div[@class="song"]/p[3]')  #p是之前标签的直系标签,然后加上三,就是第三个标签,注意!!!这里的索引定位不是从0开始的,而是1!!!
注意!!!这里的索引定位不是从0开始的,而是1!!!

三、学会标签定位后,下一步就是如何取文本了

取文本:(标签中间所存储的文本内容)

1.第一种形式
r=tree.xpath('//div[@class="tang"]/ul/li[5]/a')
#也可以是:
r=tree.xpath('//div[@class="tang"]//li[5]/a')
#a标签获取到了。获取文本在其后加/text()

例如:

r=tree.xpath('//div[@class="tang"]//li[5]/a/text()')
print(r)

获取结果:

>>>['杜牧']

最终发现这个输出结果是存在在一个列表当中的,若想取得字符串,那就在后面加一个:[0]

   r=tree.xpath('//div[@class="tang"]//li[5]/a/text()')[0]
 >>>杜牧
2.第二种形式
 <li><i>度蜜月</i></li>     第七个li标签   (非直系标签里文字的获取)
r=tree.xpath('//li[7]//text()')
#     - /text()  获取标签下直系的文本内容
#     - //text()  获取非直系标签下的文本内容
3. 以上都是一个标签里的文本获取,如果想要获取div下面的所有标签文本怎么办?

首先必不可少的属性定位:‘//div[@class=“tang”]’

r=tree.xpath('//div[@class="tang"]//text()')

——取属性:(取得定位到标签所对应属性的数值/属值?)

四、 /@attrName(格式)

例如:想要获取img里src储存的值:

<div class="song">
    <img src="http://www.baidu.com/meinv.jpg" alt="" />
</div>

输入代码:

 r=tree.xpath('//div[@class="song"]/img/@src')
 print(r)

输出:

   >>>['http://www.baidu.com/meinv.jpg']

五、xpath图片数据爬取要点

1.如果爬取标题的过程中,爬取文字出现乱码情况,应该手动修改encoding,尝试两个方法:

encoding='utf-8'

或者:

title=title.encode('iso-8859-1').decode('gbk')#title是出现乱码的区域

2.将所爬取的资源下载进入文件夹:请求图片,进行持久化存储;

img_data=requests.get(url=img_src,headers=headers).content,,,
img_path='picLibs/'+img_name
with open(img_path,'wb') as fp:      ###文件需要打开多次,每打开一次就要需要往文件夹里写入图片一次,循环外部创建一个文件夹:
    fp.write(img_data)
    print(img_name,"下载成功!")
if not os.path.exists('./picLibs'):
    os.mkdir('./picLibs')
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值