爬虫匹配中的一些字符所代表的意思
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)
和上面所说的一样,无非就是定位、匹配、提取
分享一个网站,艺术设计的,感兴趣的去看看,懂得都懂
艺术设计