1. 程式人生 > >Windows下使用python-nmap庫可能遇到的問題及解決方法(續)

Windows下使用python-nmap庫可能遇到的問題及解決方法(續)

      之前,我有寫過一篇Blog關於相關問題的解決方案,文章地址。最近,在Windows下配置python-nmap時,又遇到了一些問題。總結記錄一下。

      關於”nmap program was not found in path”問題的解決辦法:

      首先,我本機安裝了最新的Python-2.7.10和nmap-6.49BETA4。我還是打算用原來的python-nmap-0.2.4(官網最新版本已經到了python-nmap-0.4.0,關於它我們後續再說)。一切安裝都OK之後,在命令列下執行一下python-nmap-0.2.4下的example.py檔案,得到了如下的結果:

p3

      我去,怎麼還是這個問題呢?參考前一篇文章的配置,結果毫無作用呀!什麼鬼?!我修改了好多地方的配置,還是不知道什麼情況。好吧,我最後決定在Pycharm除錯執行一下,看看到底是什麼鬼。除錯關鍵行如下圖所示:

p4

      從除錯的結果看,應該是沒有問題的,nmap_path已經賦值了。(突然,我就覺得似乎第一篇文章關於python-nmap問題中,提供的增加nmap的本地路徑似乎也沒啥必要嘛?!)接著往下看,看它到底在哪裡丟擲異常了。找到了,如下圖所示:

p7

      這是什麼?is_nmap_found預設為True,判斷是否正則匹配,不匹配則賦值False。看來是正則匹配出問題了。原來,python-nmap判斷是否安裝了nmap的方法就是在找到的nmap執行路徑下執行如下命令:

nmap -V

      如果成功了,命令的返回值如下圖所示:

p6

      注意!這裡有個坑!現在,採用https協議的網站越來越多了。從返回結果看,提供的nmap官網地址所採用的也是https協議。問題來了,我們看下python-nmap-0.2.4中的正則匹配:

regex = re.compile('Nmap version [0-9]*\.[0-9]*[^ ]* \( http://nmap\.org \)')

     竟然判斷的是http協議有木有。這樣,無論怎麼都匹配不上,所以得到的判斷條件總是False,最後也就丟擲了異常,說找不到nmap。知道了這點就好辦了,稍微修改一下nmap.py中的正則表示式,修改後的正則表示式如下所示:

regex = re.compile('Nmap version [0-9]*\.[0-9]*[^ ]* \( http(|s)://.* \)')

      刪除“C:\Python27\Lib\site-packages\nmap”下副檔名為pyc的檔案,再次執行example.py,如下圖所示:

p8

      一切正常了。如果使用的老版本的python-nmap,而nmap安裝的又是最新版本的,就要注意”nmap -V”結果顯示中使用的是https協議,而python-nmap中正則表示式判斷的是http協議,稍微修改一下就OK了。

      關於“close_fds is not supported on Windows platforms if you redirect stdin/stdout/stderr”問題的解決辦法:

      既然官網放出了最新的python-nmap-0.4.0版本,那就試用一下最新版本吧。安裝一切OK之後,我來試一下,如下圖所示:

p1

      我去,這就是個什麼鬼?問題不斷啊!冷靜一下,我們來查下Python 2.7.10 documentation,看看subprocess.Popen這個函式是幹啥的。感覺比較重要的部分在這裡:

If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed. (Unix only). Or, on Windows, if close_fds is true then no handles will be inherited by the child process. Note that on Windows, you cannot set close_fds to true and also redirect the standard handles by setting stdin, stdout or stderr.

      難道是預設值的問題,我們來修改一下預設值,從True改為False試試:

p = subprocess.Popen([nmap_path, '-V'], bufsize=10000, stdout=subprocess.PIPE, close_fds=False)

      再次執行,看一下:

p2

      不報錯了,執行正常了。看來Linux下和Windows下還是有些不同的。所以在Windows下要使用python-nmap-0.4.0的話,記得把這個預設值改為False或者直接刪掉函式申明中的賦值就好(因為預設值就是False)。

      好了,就這麼多,如果對你有用,那是最好不過的了。