项目背景
工作中发现AP存在弱密码情况,需要登录AP进行弱密码修改,AP的登录IP无法批量获取,仅能通过登录AC查看,AC通过http进行登录。
项目思路
- 登录AC(通过requests库去获取AC的页面信息)
- 获取IP信息(通过xpath获取IP信息)
- 存放IP信息(获取信息后写入excel文件)
项目实现
- 通过requests进行页面的获取,通过开发者工具我发现了AP信息需要通过get方式去请求http://ip/func/web_main/display/wireless_control/ap_info_management进行获取。
- 获取数据并进行清洗后开始通过xpath来获取我们需要的信息,获取的过程中出现了ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.的报错,经过搜索了解到是因为数据中包含了XML 声明(encoding declaration)的 Unicode 字符串 所以这里采用正则库的sub方法来替换声明为空。
- 通过xpath完成数据提取出数据后我们通过pandas库将数据存放到excel文件,命名采用了时间戳用于避免数据覆盖,且在完成数据导出后弹出提示框告知用户已完成数据操作。
项目笔记
本次项目新了解到以下知识点:
- xpath的二次使用,在xpath完成tree.xpath的提取操作后,迭代进行在已提取的元素中进行二次数据提取。
项目代码
♾️ python 代码:
from datetime
import requests
from lxml import etree
import re
import pandas as pd
import pyautogui
# 定义会话:保持会话状态,不需要重复指定headers,自动管理cookie,复用headers。
# ==================== 1. 创建会话并设置 headers ====================session = requests.Session()
session.headers = {
"accept": "***",
"accept-language": "***",
"cookie": "***",
"user-agent": "***"
}
# ==================== 2. 获取 AP 列表页面 ====================try:
text = session.get('http://172.20.253.253/func/web_main/display/wireless_control/ap_info_management')
except requests.RequestException as e:
print(f"❌ 请求失败:{e}")
pyautogui.alert(f"请求失败:{e}", "错误")
exit()
# 设置内容的编码
text.encoding = 'utf-8'
# ==================== 3. 清洗 XML 声明 ====================content = re.sub(r'<\?xml.+\?>', '', text.text)
tree = etree.HTML(content)
aplist = []
data = tree.xpath('//*[@id="ap_info_manage"]//gbody//tr')
for index, tr in enumerate(data, start=1):
apinfo = {
'index': index,
'aptype': (tr.xpath('./td/modelnum/text()') or [''])[0].strip(), # strip()去掉字符串“开头”和“结尾”的空格、换行、制表符等空白字符
'sn': (tr.xpath('./td/sequencenum/text()') or [''])[0].strip(),
'ip': (tr.xpath('./td/apip/text()') or [''])[0].strip(),
'mac': (tr.xpath('./td/apmac/text()') or [''])[0].strip(),
}
aplist.append(apinfo)
df = pd.DataFrame(aplist, columns=['index', 'aptype', 'sn', 'ip', 'mac'])
df.rename(columns={
'index': '序号',
'aptype': '型号',
'sn': '序列号',
'ip': 'IP地址',
'mac': 'MAC地址'
}, inplace=True)
# inplace 就地修改,如果不添加此参数,需要写为 df = df.rename....
df.to_excel(f"迪普AP信息_{datetime.now():%Y%m%d_%H%M}.xlsx", index=False)
print("🎉 爬取完成,数据已导出!")
pyautogui.alert(f"已成功导出 {len(aplist)} 条 AP 数据!", "导出完成")
"""
DataFrame 二维表格数据结构
df = DataFrame = data frame 数据表格的缩写
columns 列名列表(存放了每列的开头)
"""