BeautifulSoup模板简单应用-提取html指定数据(api_name/api_method/api_path,请求body/请求header/pagam参数)
from bs4 import BeautifulSoup
import re
import os.path
import itertools name='newcrm'
source_file_path='./'+name+'.html' def get_apiInfo():
with open(source_file_path,encoding='utf-8') as api_file:
fileInfo=api_file.read()
soup = BeautifulSoup(fileInfo,'lxml') #这里没有装lxml的话,把它去掉用默认的就好
#匹配带有class属性的div标签
divList = soup.find_all('div', attrs={'class': re.compile("api-one")})
# print(len(divList))
apiInfo_list=[]#存放所有的api_list
try:
for alltag in divList:
h3List=alltag.find_all('h3')#在每个div标签下,查找所有的h3标签(包含接口名称)
pList = alltag.find_all('p') #在每个div标签下,查找所有的p标签(包含请求url与请求方法)
tableList=alltag.find_all("table")#匹配div下所有线程的table标签(取出header字段/body字段)
dictInfo={}
api_descride_name_list,api_descride_example_list,api_descride_type_list=[],[],[]
'''所有的接口描述信息:名称/描述/类型'''
query_Param_name_list,query_Param_type_list,query_Param_IsNeed_list=[],[],[]
query_Param_describe_list,query_Param_example_list=[],[]
'''所有的query参数信息:名称/类型/是否必填/描述,主要用于get请求'''
body_Param_name_list,body_Param_type_list,body_Param_IsNeed_list=[],[],[]
body_Param_describe_list,body_Param_example_list=[],[]
'''所有的body参数信息:名称/类型/是否必填/描述,主要用于post/put/delete请求'''
header_Param_name_list,header_Param_type_list,header_Param_IsNeed_list=[],[],[]
header_Param_describe_list,header_Param_example_list=[],[]
'''所有的header参数信息:名称/类型/是否必填/描述'''
# if divList.index(alltag)==len(divList):
if not len(pList)<3:#如果请求方式/请求url为空则不执行后面的程序
api_name=h3List[0].string.strip()#匹配h3标签下的接口名称
api_method=pList[1].string.strip()#这里提取请求方式
api_path=pList[2].string.strip() #这里提取url,并去除空格
dictInfo['api_name']=api_name
dictInfo['api_method']=api_method
dictInfo['api_path']=api_path
header_list=[]#存放header值
body_list=[]#存放body值
query_list=[]#存放query值
api_descride_list=[]#存放所有接口描述信息
# print(api_name)
# print(api_method)
# print(api_path)
IsEmpty_str='Null_Str'#处理匹配为空时的字符串占位符
if not tableList in([],None):
for table in tableList:
table_title=table.tr.th.span.string#匹配table表头
table_thead=table.find_all('thead')#匹配table里的所有thead标签:字段title(描述)
table_tbody=table.find_all('tbody')#匹配字段value
tbody_temp_list1,tbody_temp_list2=[],[]#临时存放接口描述数据
for tbody in table_tbody:
tbody_key_type=tbody.find_all('th')#匹配出字段的类型
tbody_key_field=tbody.find_all('td')#匹配出字段的value
for tbody_name in tbody_key_field :#取出所有字段
if not tbody_name.string is None:
tbody_key=tbody_name.string.strip()
else:
tbody_name=IsEmpty_str#处理为空的情况
tbody_key=tbody_name
#将能够被5整除的字段放入body中(代表的是header/body)
# print(tbody_name)
if len(tbody_key_field)%5==0:
if table_title in('Query参数名'):
'''如果table的名称是Query,则添加到Query列表中'''
query_list.append(tbody_key)
elif table_title in('Body参数名'):
'''如果table的名称是body,则添加到body列表中'''
body_list.append(tbody_key)
elif table_title in('Header参数名'):
'''如果table的名称是header,则添加到header列表中'''
header_list.append(tbody_key)#将能够被5整除的字段放入body中(代表的是header/body)
elif len(tbody_key_field)%2==0 and table_title ==('参数名'):
tbody_temp_list1.append(tbody_key)#剩下的放入参数名信息中,代表的是参数名描述
# print(header_list)
# print(body_list)
# print(tbody_temp_list1)
if not tbody_key_type==[]:
for tbody_type in tbody_key_type:
if type(tbody_type)!=(str,int):#只处理type为tag的
if not (tbody_type.string is None) :
tbody_field=tbody_type.string.strip()
tbody_temp_list2.append(tbody_field)
else:
tbody_type=IsEmpty_str#处理为空的情况
tbody_temp_list2.append(tbody_type)
# print(tbody_temp_list2)
temp_num=int(len(tbody_temp_list1)/len(tbody_temp_list2))
#计算出两个list的对应关系,这里是2:1,
#需要添加tbody_temp_list1key添加两次后在添加tbody_temp_list2的值
for temp_tuple in enumerate(tbody_temp_list2):
#将tbody_temp_list1/tbody_temp_list2的元素添加至api_descride_list
#'''temp_tuple:是一个元组,第一个参数是index,第二个是value'''
for num in range(temp_num):
#因为tbody_temp_list1/tbody_temp_list2是多对1,
#因为接口描述里的type是单独的th标签里的值,
#而其他的值是td标签里面的值,所以需要将两个列表的元素进行合并
api_descride_list.append(tbody_temp_list1[temp_tuple[0]*(temp_num)+num])
else:
api_descride_list.append(temp_tuple[1])
# print(header_list)
# print(body_list)
# print(api_descride_list)
#
if not header_list in([],None):#处理header列表中字段为空的情况
for n,m in enumerate(header_list):
#删除filed(不存在)的相关元素,这个是apizza导出的bug导致的
#因为列表存在多个相同的值,所以不能使用index方法来获取元素下标,
#使用enumerate来获取list的值与对应的下标
if m in("是","否") :#根据m的值找到对应的下表n
try:
if header_list[(n+3)]==IsEmpty_str:
#如果n后面的第三个元素不是一个字段,而是事先定义的为空的字符串,则删除索引后面的五个元素
for i in range(5):
del header_list[n+3]
except IndexError as error:
pass for header_data in enumerate(header_list):#将列表中的值分别添加至各个列表
if header_data[0]==0 or header_data[0]%5==0 :
header_Param_name_list.append(header_data[1])
elif header_data[0]==1 or header_data[0]%5==1 :
header_Param_type_list.append(header_data[1])
elif header_data[0]==2 or header_data[0]%5==2:
header_Param_IsNeed_list.append(header_data[1])
elif header_data[0]==3 or header_data[0]%5==3:
header_Param_describe_list.append(header_data[1])
elif header_data[0]==4 or header_data[0]%5==4:
header_Param_example_list.append(header_data[1]) if not query_list in([],None):
for n,m in enumerate(query_list):#处理query列表中字段为空的情况
#因为列表可能存在多个相同的值,所以不能使用index方法来获取元素下标,
#使用enumerate来获取list的值与对应的下标
if m in("是","否") :#根据m的值找到对应的下表n
try:
if query_list[(n+3)]==IsEmpty_str:
#如果n后面的第三个元素不是一个字段,而是事先定义的为空的字符串,
#则删除索引后面的五个元素
for i in range(5):
del query_list[n+3]
except IndexError as error:
pass
for query_data in enumerate(query_list):#将列表中的值分别添加至各个列表
if query_data[0]==0 or query_data[0]%5==0 :
query_Param_name_list.append(query_data[1])
elif query_data[0]==1 or query_data[0]%5==1 :
query_Param_type_list.append(query_data[1])
elif query_data[0]==2 or query_data[0]%5==2:
query_Param_IsNeed_list.append(query_data[1])
elif query_data[0]==3 or query_data[0]%5==3:
query_Param_describe_list.append(query_data[1])
elif query_data[0]==4 or query_data[0]%5==4:
query_Param_example_list.append(query_data[1]) if not body_list in([],None):
for n,m in enumerate(body_list):#处理body列表中字段为空的情况
#因为列表可能存在多个相同的值,所以不能使用index方法来获取元素下标,
#使用enumerate来获取list的值与对应的下标
if m in("是","否") :#根据m的值找到对应的下表n
try:
if body_list[(n+3)]==IsEmpty_str:
#如果n后面的第三个元素不是一个字段,而是事先定义的为空的字符串,
#则删除索引后面的五个元素
for i in range(5):
del body_list[n+3]
except IndexError as error:
pass
for body_data in enumerate(body_list):#将列表中的值分别添加至各个列表
if body_data[0]==0 or body_data[0]%5==0 :
body_Param_name_list.append(body_data[1])
elif body_data[0]==1 or body_data[0]%5==1 :
body_Param_type_list.append(body_data[1])
elif body_data[0]==2 or body_data[0]%5==2:
body_Param_IsNeed_list.append(body_data[1])
elif body_data[0]==3 or body_data[0]%5==3:
body_Param_describe_list.append(body_data[1])
elif body_data[0]==4 or body_data[0]%5==4:
body_Param_example_list.append(body_data[1]) if not api_descride_list in([],None):#处理header列表中字段为空的情况
for api_descride_data in enumerate(api_descride_list):#将列表中的值分别添加至各个列表
if api_descride_data[0]==0 or api_descride_data[0]%3==0 :
api_descride_name_list.append(api_descride_data[1])
elif api_descride_data[0]==1 or api_descride_data[0]%3==1 :
api_descride_example_list.append(api_descride_data[1])
elif api_descride_data[0]==2 or api_descride_data[0]%3==2:
api_descride_type_list.append(api_descride_data[1]) if not header_list in(None,[]):
dictInfo['Header']={}
dictInfo['Header']['参数名']=header_Param_name_list
dictInfo['Header']['类型']=header_Param_type_list
dictInfo['Header']['必需']=header_Param_IsNeed_list
dictInfo['Header']['描述']=header_Param_describe_list
dictInfo['Header']['示例']=header_Param_example_list if not query_list in(None,[]):
dictInfo['Query']={}
dictInfo['Query']['参数名']=query_Param_name_list
dictInfo['Query']['类型']=query_Param_type_list
dictInfo['Query']['必需']=query_Param_IsNeed_list
dictInfo['Query']['描述']=query_Param_describe_list
dictInfo['Query']['示例']=query_Param_example_list if not body_list in(None,[]):
dictInfo['Body']={}
dictInfo['Body']['参数名']=body_Param_name_list
dictInfo['Body']['类型']=body_Param_type_list
dictInfo['Body']['必需']=body_Param_IsNeed_list
dictInfo['Body']['描述']=body_Param_describe_list
dictInfo['Body']['示例']=body_Param_example_list if not api_descride_list in(None,[]):
dictInfo['接口说明']={}
dictInfo['接口说明']['参数名']=api_descride_name_list
dictInfo['接口说明']['描述']=api_descride_example_list
dictInfo['接口说明']['类型']=api_descride_type_list # dictInfo['header_list']=header_list
# dictInfo['body_list']=body_list
# dictInfo['api_descride_list']=api_descride_list
apiInfo_list.append(dictInfo) except Exception as error:
# pass
raise(error)
return apiInfo_list
def write_apiInfo_to_file():
source_data=get_apiInfo()#获取数据来源
print(len(source_data))
file_path='./'+name+'-apiInfo.txt'
with open(file_path,'w',encoding='utf-8') as file:
file.write(str(source_data)) write_apiInfo_to_file()
BeautifulSoup模板简单应用-提取html指定数据(api_name/api_method/api_path,请求body/请求header/pagam参数)的更多相关文章
- thinkPHP框架 简单的删除和修改数据的做法 和 模板继承的意思大概做法
BiaodanController.class.php控制器页面 <?php namespace Admin\Controller; use think\Controller; class Bi ...
- 爬虫基础库之beautifulsoup的简单使用
beautifulsoup的简单使用 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: ''' Beautiful Soup提供一些简单的.p ...
- sql server编写archive通用模板脚本实现自动分批删除数据
博主做过比较多项目的archive脚本编写,对于这种删除数据的脚本开发,肯定是一开始的话用最简单的一个delete语句,然后由于部分表数据量比较大啊,索引比较多啊,会发现删除数据很慢而且影响系统的正常 ...
- 简单一招实现json数据可视化
开发一个内部功能时碰到的需求,要把json数据在页面上展示出来,平时浏览器会安装jsonView这样的扩展来看json数据,但是程序要用到的话该怎么办呢?今天在网上搜索的时候,发现了这个小技巧,分享一 ...
- Python使用Tabula提取PDF表格数据
今天遇到一个批量读取pdf文件中表格数据的需求,样式大体是以下这样: python读取PDF无非就是三种方式(我所了解的),pdfminer.pdf2htmlEX 和 Tabula.综合考虑后,选择了 ...
- 在AJAX里 使用【 XML 】 返回数据类型 实现简单的下拉菜单数据
在AJAX里 使用XML返回数据类型 实现简单的下拉菜单数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...
- 在AJAX里 使用【 JSON 】 返回数据类型 实现简单的下拉菜单数据
在AJAX里 使用JSON返回数据类型 实现简单的下拉菜单数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//E ...
- mtail 提取应用日志数据到时序数据库的工具-支持prometheus
mtail 是谷歌开源的一款很不错的应用日志提取工具,我们可以方便的用来提取应用的数据 到常见的监控系统(prometheus,stats,collectd,gragphite....) 说明: de ...
- 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据
一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...
随机推荐
- LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)
513. 找树左下角的值 513. Find Bottom Left Tree Value 题目描述 给定一个二叉树,在树的最后一行找到最左边的值. LeetCode513. Find Bottom ...
- LeetCode 566. 重塑矩阵(Reshape the Matrix)
566. 重塑矩阵 566. Reshape the Matrix 题目描述 LeetCode LeetCode LeetCode566. Reshape the Matrix简单 Java 实现 c ...
- 少儿编程|Scratch编程教程系列合集,总有一款适合你
如果觉得资源不错,友情转发,贵在分享!!! 少儿编程Scratch: 少儿编程Scratch第一讲:Scratch完美的初体验少儿编程Scratch第二讲:奇妙的接球小游戏少儿编程Scratch第三讲 ...
- Js学习04--对象
1.如何辨别js中的对象 除了五种基本的数据类型,其他的都是对象.万物皆对象. 2.Js中对象的分类 1)内建对象 由ES标准定义的对象,在任何的ES实现中都可以使用. eg:String.Numbe ...
- NGINX 配置本地HTTPS(双向认证)
一.SSL协议加密方式 SSL协议即用到了对称加密也用到了非对称加密(公钥加密),在建立传输链路时,SSL首先对对称加密的密钥使用公钥进行非对称加密,链路建立好之后,SSL对传输内容使用对称加密. 1 ...
- Luogu3214 HNOI2011 卡农 组合、DP
传送门 火题qwq 我们需要求的是满足元素个数为\(M\).元素取值范围为\([1,2^n-1]\).元素异或和为\(0\)的集合的数量. 首先我们可以计算元素有序的方案数(即计算满足这些条件的序列的 ...
- 登录和退出Mysql
这里介绍的是通过cmd方式登录和退出Mysql的方式 一.登录命令 登录命令:mysql.exe -h主机地址 -P端口 -u用户名 -p密码 即依次输入服务器地址.服务器监听的端口.用 ...
- 基于MBT的自动化测试工具——GraphWalker介绍和实际使用
GraphWalker是一个开源的基于模型的自动化测试工具,它可以用来通过图形测试模型来自动生成测试用例. 本文主要描述了使用yed画出FSM, EFSM模型图(常见的流程图),然后使用GraphWa ...
- 并发编程之Disruptor并发框架
一.什么是Disruptor Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JV ...
- 能够提高PHP的性能的一些注意事项
1. 如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍.(静态类调用属性和方法,只可以调用静态属性和方法.self::方法名().self::属性名.只有实例化 ...