Python爬取Linux命令,并保存于Excel
学习Linux运维,最难过的不是看不懂字符界面,而是不懂命令,前几日发现一个网站,上面保存了很多Linux的命令,唯一不足的就是网页并没有写明各个命令的归属,命令的功能。
无情???315个命令,找自己想要的命令怎么查?
好在我们有工具,python带你爬取所有命令,并详细保存。
一、爬取篇
首先,查看网页源代码,看看自己会不会爬,不会?出门左转。
一条命令,右键查看网页源代码。
发现我们要的信息在<dt>
与<dd>
这两个标签里。
- 首先,获取每一个命令网页下的内容。
import requests
def get_url_comment(url):
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 "
"Core/1.70.3741.400 QQBrowser/10.5.3863.400"
}
try:
r = requests.get(url ,headers = headers, timeout = 30)#获得url的相关参数
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except Exception as e :
return "网页爬取异常" , r.status_code ,e#返回状态码
if __name__ == '__main__':
for i in tqdm(range(1,316)):
a = get_url_comment(r"http://www.ourlinux.net/index.php?mod=linuxcommand&act=show&id=" + str(i))
linux_fianl_list.append(explain_url(a))
从网页链接中可以看出,下一条命令只需更改每个命令网页后面的数字。r"http://www.ourlinux.net/index.php?mod=linuxcommand&act=show&id=" + str(i)
i就是要个更改的数字。好,网页内容获取了,开始解析!!!
- BeautifulSoup解析网页数据
从刚刚查看到的网页源码可以看出
<div style="margin-top: 10px;">
<ol class="breadcrumb">
<li><a href="?mod=linuxcommand">Linux命令大全</a></li>
<li><a href="index.php?mod=linuxcommand&type=文档编辑">文档编辑</a></li>
<li class="active">rgrep</li>
<!--<li >Data</p>-->
</ol>
</div>
============================================
<p class="text-center"><strong>rgrep</strong><br />
<i>作者: 日期:2003-05-30 14:41:16</i><br />
</p><dt>〔功能说明〕:</dt><dd>递归查找文件里符合条件的字符串。——rgrep(recursive grep)</dd><dt>〔语法〕:</dt><dd>rgrep [-?BcDFhHilnNrv][-R<范本样式>][-W<列长度>][-x<扩展名>][--help][--version][范本样式][文件或目录...]</dd><dt>〔补充说明〕:</dt><dd>rgrep指令的功能和grep指令类似,可查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设rgrep指令会把含有范本样式的那一列显示出来。</dd><dt>〔参数〕:</dt><dd> -? 显示范本样式与范例的说明。<br />
-B 忽略二进制的数据。<br />
-c 计算符合范本样式的列数。<br />
-D 排错模式,只列出指令搜寻的目录清单,而不会读取文件内容。<br />
-F 当遇到符号连接时,rgrep预设是忽略不予处理,加上本参数后,rgrep指令就会读取该连接所指向的原始文件的内容。<br />
-h 特别将符合范本样式的字符串标示出来。<br />
-H 只列出符合范本样式的字符串,而非显示整列的内容。<br />
-i 忽略字符大小写的差别。<br />
-l 列出文件内容符合指定的范本样式的文件名称。<br />
-n 在显示符合坊本样式的那一列之前,标示出该列的列数编号。<br />
-N 不要递归处理。<br />
-r 递归处理,将指定目录下的所有文件及子目录一并处理。<br />
-R<范本样式> 此参数的效果和指定“-r”参数类似,但只主力符合范本样式文件名称的文件。<br />
-v 反转查找。<br />
-W<列长度> 限制符合范本样式的字符串所在列,必须拥有的字符数。<br />
-x<扩展名> 只处理符合指定扩展名的文件名称的文件。<br />
--help 在线帮助。<br />
--version 显示版本信息。</dd> </dl>
</div>
</div>
</div>
我们要的内容,在第一段代码的<o1>
的儿子节点内,具体功能内容在<dt>
与<dd>
标签内。解析后,通过find(),find_all()
,来获得这些标签内容。
解析过程,我们要考虑数据结构,什么样的数据结构可以存储这么庞大数据,而且可以很好访问。网页代码中我们可以看出,像文档编辑,rgrep
,可以存到一个列表中,方便以后便利,具体内容我们采用字典来存贮,更加好访问。
所采用的数据结构:
["所属功能" , "名称" , {'[功能描述]':'XXXX','[参数]':'XXXX' , ......}]
代码:
from bs4 import BeautifulSoup
import bs4
def explain_url(url_content):
i = 1
linux_list_nametype = []
linux_dict_factiontype = {}
soup = BeautifulSoup(url_content, "html.parser")#解释
linux_command_type = soup.find("ol").children#遍历o1下的li标签
linux_command_faction = soup.find_all(["dt","dd"])
for li in linux_command_type:
if li.string == "Linux命令大全" or li.string == "<li >Data</p>" or li.string == "\n":#清洗数据
pass
else:
linux_list_nametype.append(li.string)
for dtdd in linux_command_faction:
if "<dt>" in str(dtdd):
try:
linux_dict_factiontype[dtdd.string] = linux_command_faction[i].text
i += 2
except:
continue
linux_list_nametype.append (linux_dict_factiontype)
return linux_list_nametype
- 写入excel
写入需要注意的是遍历每条命令的时候,行不变,列后移相应单位。
from tqdm import tqdm
import xlwt
def write_excel(final_list):
row = 1
book = xlwt.Workbook()
sheet = book.add_sheet("linux命令大全")
for each_1 in final_list:
col = 0
for each_2 in each_1:
if isinstance(each_2 , dict):
col_temp = 2
for k , v in each_2.items():
sheet.write(row , col_temp , k+v)
col_temp += 1
else:
sheet.write(row, col, each_2)
col += 1
row += 1
book.save(r"D:\桌面\Linux命令大全.xls".strip('\u202a'))
二、效果篇
代码运行没超过1min
,速度客观,要是会异步爬取,那岂不是爽歪歪?(可惜我不会)
爬取结果如下:
最后,自己可以在调整一下行高即可。ctrl + F
查询想要的结果。
当然,我其实还可以做一个GUI来展示,通过xlrd库
读取excel,以此查询结果,并打包成.exe
来方便查取,但是爷懒,excel不香嘛???
三、总代码
import requests
from bs4 import BeautifulSoup
import bs4
from tqdm import tqdm
import xlwt
def get_url_comment(url):
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 "
"Core/1.70.3741.400 QQBrowser/10.5.3863.400"
}
try:
r = requests.get(url ,headers = headers, timeout = 30)#获得url的相关参数
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except Exception as e :
return "网页爬取异常" , r.status_code ,e#返回状态码
def explain_url(url_content):
i = 1
linux_list_nametype = []
linux_dict_factiontype = {}
soup = BeautifulSoup(url_content, "html.parser")#解释
linux_command_type = soup.find("ol").children#遍历o1下的li标签
linux_command_faction = soup.find_all(["dt","dd"])
for li in linux_command_type:
if li.string == "Linux命令大全" or li.string == "<li >Data</p>" or li.string == "\n":#清洗数据
pass
else:
linux_list_nametype.append(li.string)
for dtdd in linux_command_faction:
if "<dt>" in str(dtdd):
try:
linux_dict_factiontype[dtdd.string] = linux_command_faction[i].text
i += 2
except:
continue
linux_list_nametype.append (linux_dict_factiontype)
return linux_list_nametype
def write_excel(final_list):
row = 1
book = xlwt.Workbook()
sheet = book.add_sheet("linux命令大全")
for each_1 in final_list:
col = 0
for each_2 in each_1:
if isinstance(each_2 , dict):
col_temp = 2
for k , v in each_2.items():
sheet.write(row , col_temp , k+v)
col_temp += 1
else:
sheet.write(row, col, each_2)
col += 1
row += 1
book.save(r"D:\桌面\Linux命令大全.xls".strip('\u202a'))
if __name__ == '__main__':
linux_fianl_list = []
for i in tqdm(range(1,316)):
a = get_url_comment(r"http://www.ourlinux.net/index.php?mod=linuxcommand&act=show&id=" + str(i))
linux_fianl_list.append(explain_url(a))
write_excel(linux_fianl_list)
想要那份excel的小伙伴私聊俺~~