爬虫 xpath() 基础+提升 必备秘籍 超详细 建议保留

7 篇文章 17 订阅

爬虫匹配中的一些字符所代表的意思

TODO         表达式                      描述
TODO         nodename             选取此节点中的全部接节点
TODO         /                    从当前节点选取直接子节点
TODO         //                   从当前节点选取子孙节点
TODO         .                    选取当前节点
TODO         ..                   选取当前节点的父节点
TODO         @                    获取属性

注意,此处非常重要,学爬虫必不可少

当你了解了一些爬虫了之后你就会发现爬虫就是模仿浏览器(此处不含cookie,后期会单独介绍cookie)对网页的html中的数据进行读取和保存,其实这些工作人工也可以做,但是人工可能会缺失某些数据且因为数据量大的原因所需人工量大就使人工费变得很高。某种语言和技术的发展背后肯定有推动发展的因素,所以,爬虫技术应运而生。

注意:::
因为爬取具体的网站涉及到版权问题,我也是尝试了很久很久,最终代码里的网址用“ 网站地址 ”表示
注意:::
因为爬取具体的网站涉及到版权问题,我也是尝试了很久很久,最终代码里的网址用“ 网站地址 ”表示
注意:::
因为爬取具体的网站涉及到版权问题,我也是尝试了很久很久,最终代码里的网址用“ 网站地址 ”表示

重要事说三遍

找到User-Agent,因为这个网站没有涉及到登录(只有登陆后才能获取相应的操作),所以不用获取cookie。

**

xpath_通用规则

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)



#初始化xpath        etree  可以自动修正文本
# html=etree.HTML(response.text,etree.HTMLParser())
html=etree.HTML(response.text)
result=etree.tostring(html)
KK=result.decode("utf-8")
print(KK)
结果:

在这里插入图片描述
response.text 获取文本
result=etree.tostring(html) 中etree函数是使获取的html文本自动格式化,不然获取的html文档是乱糟糟的

可以发现获取的是一长段,整个网页的html,下面我们将对这些html进行一些操作和匹配,取出需要的数据,粗略看了一下,国外的网站,基本上没有发现中文。(用国内网访问竟然非常丝滑)

**

定位所有节点

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)
#xpath()进行节点定位
result=html.xpath('//*')
#xpath 进行  li节点
result1=html.xpath('//li')[0]
print(result)
print("*"*88)
print(result1)
结果:

在这里插入图片描述
**

定位子节点

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)

# 选取所有子节点   li节点下的a节点(标签)
result=html.xpath('//li/a')     #  /  子节点
#选取所有子节点
result1=html.xpath('//li//a')    #  //   子孙节点
print(result)


result2=html.xpath('.//ul//a')
print(result2)
结果

在这里插入图片描述
**

定位父节点

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)

#  .. 寻找父节点
result=html.xpath('//a[@href="/sites/silvia-sguotti"]/../@class')
print(result)
result2=html.xpath('//a[@href="/sites/silvia-sguotti"]/parent::*/@class')
print(result2)

//a[@href="/sites/silvia-sguotti"]/../@class
指的是//当前所选中的子孙节点a节点且class
属性为"/sites/silvia-sguotti",当前节点的父节点

result2也是同一个意思,不过就是方法复杂些,一般不使用
在这里插入图片描述

结果

在这里插入图片描述
**

属性匹配

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)

# @过滤属性
result=html.xpath('//li[@class="col-3"]')
print(result)

首先得到url,headers里面是"User-Agent",为后面request.get方法调用url,headers为装了浏览器做铺垫,伪造浏览器向服务器发送请求

结果

在这里插入图片描述
'//li[@class=“col-3”]'我们可以发现[@class=“col-3”]通过class属性为 "col-3 "定位class节点,然后匹配出当前节点下的所有li节点。通过图片结果我们可以发现都是对象,但是可以明显的发现每个对象都有一个li节点,因为节点下还有其他的节点,所以干脆封装成为一个节点。
**

文本获取

**
初始化xpath,模仿浏览器访问操作不变,只需要改变result即可

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
print(response.text)
result=html.xpath('//div[@class="row"]/h3/a/text()')[0]
print(result)

可以清晰地发现定位class="row"标签,然后定位当前目录下的h3标签下的a标签中的text文本是不是非常简单

结果

在这里插入图片描述
**

属性获取

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
#初始化xpath
html=etree.HTML(response.text)
result2=html.xpath('//li//div[@class="row"]//a/@href')
print(result2)

'//li//div[@class="row"]//a/@href' 定位到当前子孙节点li节点,找到div ,属性class="row"节点,再找其节点下的子孙节点a节点,再定位a节点下的href属性,匹配所需要的值
提取href属性下的所有:

结果

在这里插入图片描述
**

属性多值匹配

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
#初始化xpath
html=etree.HTML(response.text)
# 多属性多值匹配
result=html.xpath('//div[@class="row row-2col"]/div[@class="box-right"]/text()')
print(result)
#  TODO    contains 方法  ,result2和上面的result1 结果一致
result2=html.xpath('//div[contains(@class,"row")]/div[@class="box-right"]/text()')
print(result2)

print(result2==result)      #True           ==     判断value值       value值一样
print(result is result2)    #False          is     判断地址是否一样    存储地址不一样

('//div[@class="row row-2col"]/div[@class="box-right"]/text()'),因为class有多个属性,所以两个属性都要匹配,这样准确地会很高,弱国只匹配一个很有可能会什么都匹配不到。然后后面和前面一样了


('//div[contains(@class,"row")]/div[@class="box-right"]/text()'),和第一个结果一样,但是运用了contains函数,比较简单方便,建议使用。

赠送一个清洗数据的方法

# TODO  清洗数据
for i in result:
    print(i.strip())

循环遍历提取到的东西,然后运用python里面的strip()函数即可清洗数据,要想讲一段字符分割提取需要的一部分就需要python的spilt()函数了。

结果:

在这里插入图片描述
**

多属性匹配

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
#初始化xpath
html=etree.HTML(response.text)
result1=html.xpath('//div[@class="wrapper "]//div[@class="pull-left"]//text()')
print(result1)
print('*'*80)
result=html.xpath('//nav[(@class="nav-main")and(@id="nav-main")]//span[contains(@class,"link-underlined")and(@data-menu-id="menu-lang")]/text()')           #  ['\n                    English\n                ']
print(result)
结果

在这里插入图片描述
**

多属性匹配无非就是像if判断里面的与操作,只有当与两边的条件全部为真才能进行下面的。多属性值判断也是一样的意思。就是通过更多的限制去匹配所需要匹配的内容。这样的效果会比较差,因为只能匹配比较死的数据,数据的量有一定限制,但是当反爬虫足够强大时也不失为一个好的方法。

**

**

按序选择

**

from lxml import etree

import requests
url="网站地址"
headers={
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
}
response=requests.get(url,headers=headers)
#初始化xpath
html=etree.HTML(response.text)
# 按序匹配
result1=html.xpath('//li[1]/div[@class="box-item"]//a[@href]')
print(result1)

print("*"*100)
result=html.xpath('//li[1]/div[@class="box-item"]//a/@href')
print(result)

print("&"*88)
#按序匹配  取第一个li节点
result3=html.xpath('//li[1]/div/a/@href')
print(result3)

和上面所说的一样,无非就是定位、匹配、提取
分享一个网站,艺术设计的,感兴趣的去看看,懂得都懂
艺术设计

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不良使

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值