今天主要整理python的三种解析方法
正则表达式
1、正则解析主要是以//.和//.?的两种从而获得想要获取的数据就比如说在分页爬取的时候中间的
代码语言:javascript复制ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list = re.findall(ex, page_text, re.S)
这是一个正则表达式的一个解析式 中间的(.*?)就是用来匹配你所要的内容。 主要就是是用python所提供的re模块用于实现正则表达式的操作,在操作的时候可以使用re提供的方法(search(),match(),findall())进行字符串处理; 他们三个都有共同的参数 pattern:模式字符串 string:要进行匹配的字符串 flags:可选参数,表示标识位,用于控制匹配方式,如是否匹配字母大小写
match()
用于从字符串的开始位置进行匹配如果开始位置匹配成功择返回match对象,否则择返回None
search()
用于整个字符串中搜索第一个匹配到的值,如果匹配成功则返回search对象,如果没有匹配成功则返回None
findall()
用于匹配整个列表中所有符合正测表达式的字符串并一列表的形式返回,,没有则返回None 关于.和.?的区别 .表示匹配换行符之外的任何单字符,*表示零次或者多次,所以.和在一起就是表示出现任意字符零次或者多次。如果没有?则表示贪婪模式 比如 a.b他将会匹配最长的以a开始,以b结束的字符串 .?表示懒惰模式 比如a.?b将会匹配以a开始,以b结束匹配最短的且符合标准的字符串
代码语言:javascript复制# 编写时间2021/5/6;20:03
# 编写 :刘钰琢
# 分页爬取
import requests
import os
import re
if __name__ == '__main__':
if not os.path.exists('./fenyelibs'):
os.mkdir('./fenyelibs')
else:
print()
# 设置一个通用的url模版
url = 'https://www.qiushibaike.com/imgrank/page/%d/'
# pagenum=2
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51'
}
for item in range(1, 3):
pagenum = item
new_url = format(url % pagenum)
# print(new_url)
page_text = requests.get(url=new_url, headers=headers).text
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list = re.findall(ex, page_text, re.S)
for src in img_src_list:
new_src = 'https:' src
img_data = requests.get(new_src, headers=headers).content
img_name = src.split('/')[-1]
img_path = './fenyelibs/' img_name
with open(img_path, "wb")as file:
file.write(img_data)
print(img_name, '下载完成')
print('下载完成!!!')
bs4解析
代码语言:javascript复制# 编写时间2021/5/11;19:52
# 编写 :刘钰琢
# 针对与bs4 实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
# 通过调用BeautifulSoup对象中相关的属性或者办法进行标签定位
from bs4 import BeautifulSoup
if __name__ == '__main__':
fp = open('./text.html', 'r', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
#print(soup)
print(soup.a)#soup.tagname 返回的是HTML中第一次出现的tagname对应的标签
print('-----')
print(soup.div)
#soup.find()
print('------')
print(soup.find('div'))#相当于soup.div
#属性定位
print('---------属性定位:n',soup.find('div',class_='song'),'n')
print('--------find_all:',soup.find_all('a'))
#select
print('----selectn',soup.select('.tang'),'n')#某种选择器(id,class,标签...选择器),返回的是一个列表 只要符合选择器的要求
#层级选择器
print(soup.select('.tang > ul > li > a')[0],'n')#>是一个层级
print(soup.select('.tang > ul a')[0])#空格表示多个层级
#获取标签之间的文本数据 text 和get_text()可以获取标签中的所有文本内容
# string只可以获取该标签下面的直系文本内容
print(soup.select('.tang > ul a')[0].get_text())
print(soup.select('.tang > ul a')[0].text)
print(soup.select('.tang > ul a')[0].string,'n')
print('测试一下','n')
print(soup.find('div',class_='song').text)
#获取标签中的属性值'
print('获取标签中的属性值:n',soup.select('.tang>ul a')[0]['href'])
他这中间会有find find_all select 三种查找的犯法 find是返回查找到的第一个值 find_all是返回查找到的所有值以列表形式返回 select 某种选择器(id,class,标签…选择器),返回的是一个列表 只要符合选择器的要求 他在进行网页查找的时候要记得在他div的标签属性下加.使用>进行下一个选项如果要跨级去中的话那就要是用空格
xpath解析
代码语言:javascript复制# 编写时间2021/5/17;18:53
# 编写 :刘钰琢
from lxml import etree
import requests
if __name__ == '__main__':
print('hello python!!')
#实例化一个etree对象,并且被解析的源码也加载到了该对象中
tree=etree.parse('text.html')
#调用xpath
r=tree.xpath('/html/body/div/text()')#在HTML前边加一个/标识从根节点开始 后边的/标识一个层级
# r=tree.xpath('/html//div')#//表示多个层级
#r=tree.xpath('//div')#//标识可以从任意的位置去定位div标签
print(r)
# r1 = tree.xpath('//div[@class="sng"]/p[3]')
# r2 = tree.xpath('//div[@class="sang"]/p[3]') # 索引是从1开始的
# # print(r1)
# print(r2)
r3=tree.xpath('//div[@class="tang"]//li[5]/a/text()')[0]#取文本用/text()
print(r3)
r4=tree.xpath('//li[7]//text()')[0]#/txet()获取的是标签中直系的文本内容
#//text()获取的是标签中的非直系的内容
print(r4)
r5=tree.xpath('//li//text()')
for item in r5:
print(item)
print('----------------')
r6=tree.xpath('//div[@class="sang"]/img/@src')#取属性值用/@sttrName 可以取到标签属性当中的文本内容
print(r6)
这个他就使用的是/进行分级的 要是要想跨级进行查找的话那就要使用//