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参数)的更多相关文章

  1. thinkPHP框架 简单的删除和修改数据的做法 和 模板继承的意思大概做法

    BiaodanController.class.php控制器页面 <?php namespace Admin\Controller; use think\Controller; class Bi ...

  2. 爬虫基础库之beautifulsoup的简单使用

    beautifulsoup的简单使用 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: ''' Beautiful Soup提供一些简单的.p ...

  3. sql server编写archive通用模板脚本实现自动分批删除数据

    博主做过比较多项目的archive脚本编写,对于这种删除数据的脚本开发,肯定是一开始的话用最简单的一个delete语句,然后由于部分表数据量比较大啊,索引比较多啊,会发现删除数据很慢而且影响系统的正常 ...

  4. 简单一招实现json数据可视化

    开发一个内部功能时碰到的需求,要把json数据在页面上展示出来,平时浏览器会安装jsonView这样的扩展来看json数据,但是程序要用到的话该怎么办呢?今天在网上搜索的时候,发现了这个小技巧,分享一 ...

  5. Python使用Tabula提取PDF表格数据

    今天遇到一个批量读取pdf文件中表格数据的需求,样式大体是以下这样: python读取PDF无非就是三种方式(我所了解的),pdfminer.pdf2htmlEX 和 Tabula.综合考虑后,选择了 ...

  6. 在AJAX里 使用【 XML 】 返回数据类型 实现简单的下拉菜单数据

    在AJAX里 使用XML返回数据类型 实现简单的下拉菜单数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...

  7. 在AJAX里 使用【 JSON 】 返回数据类型 实现简单的下拉菜单数据

    在AJAX里 使用JSON返回数据类型 实现简单的下拉菜单数据 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//E ...

  8. mtail 提取应用日志数据到时序数据库的工具-支持prometheus

    mtail 是谷歌开源的一款很不错的应用日志提取工具,我们可以方便的用来提取应用的数据 到常见的监控系统(prometheus,stats,collectd,gragphite....) 说明: de ...

  9. 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

随机推荐

  1. LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)

    513. 找树左下角的值 513. Find Bottom Left Tree Value 题目描述 给定一个二叉树,在树的最后一行找到最左边的值. LeetCode513. Find Bottom ...

  2. LeetCode 566. 重塑矩阵(Reshape the Matrix)

    566. 重塑矩阵 566. Reshape the Matrix 题目描述 LeetCode LeetCode LeetCode566. Reshape the Matrix简单 Java 实现 c ...

  3. 少儿编程|Scratch编程教程系列合集,总有一款适合你

    如果觉得资源不错,友情转发,贵在分享!!! 少儿编程Scratch: 少儿编程Scratch第一讲:Scratch完美的初体验少儿编程Scratch第二讲:奇妙的接球小游戏少儿编程Scratch第三讲 ...

  4. Js学习04--对象

    1.如何辨别js中的对象 除了五种基本的数据类型,其他的都是对象.万物皆对象. 2.Js中对象的分类 1)内建对象 由ES标准定义的对象,在任何的ES实现中都可以使用. eg:String.Numbe ...

  5. NGINX 配置本地HTTPS(双向认证)

    一.SSL协议加密方式 SSL协议即用到了对称加密也用到了非对称加密(公钥加密),在建立传输链路时,SSL首先对对称加密的密钥使用公钥进行非对称加密,链路建立好之后,SSL对传输内容使用对称加密. 1 ...

  6. Luogu3214 HNOI2011 卡农 组合、DP

    传送门 火题qwq 我们需要求的是满足元素个数为\(M\).元素取值范围为\([1,2^n-1]\).元素异或和为\(0\)的集合的数量. 首先我们可以计算元素有序的方案数(即计算满足这些条件的序列的 ...

  7. 登录和退出Mysql

    这里介绍的是通过cmd方式登录和退出Mysql的方式 一.登录命令 登录命令:mysql.exe -h主机地址   -P端口   -u用户名    -p密码 即依次输入服务器地址.服务器监听的端口.用 ...

  8. 基于MBT的自动化测试工具——GraphWalker介绍和实际使用

    GraphWalker是一个开源的基于模型的自动化测试工具,它可以用来通过图形测试模型来自动生成测试用例. 本文主要描述了使用yed画出FSM, EFSM模型图(常见的流程图),然后使用GraphWa ...

  9. 并发编程之Disruptor并发框架

    一.什么是Disruptor Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易.这个系统是建立在JV ...

  10. 能够提高PHP的性能的一些注意事项

      1. 如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍.(静态类调用属性和方法,只可以调用静态属性和方法.self::方法名().self::属性名.只有实例化 ...