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的小夥伴私聊俺~~