2016-01-24 58 views
0

遇到奇怪的差異Enthought樹冠內對命令行當試圖加載和利用的urllib和/或urllib.request裏的urllib與urllib.request裏在Python3 - Enthought雨棚

這裏是我的意思。我在MacOS 10.11.3上運行Python 3.5。但我也在Windows 10機器上嘗試了這一點,我也得到了相同的結果。區別似乎在使用Canopy和使用命令行之間。

我想要做基本的屏幕抓取。基於閱讀,我認爲我應該這樣做:

from urllib.request import urlopen 
html = urlopen("http://pythonscraping.com/pages/page1.html") 
print(html.read()) 

這可以在命令提示符。

但是,在樹冠內,這是行不通的。篷裏面我得到的錯誤

ImportError: No module named request 

當冠層試圖從urllib.request裏進口的urlopen

篷內執行,這是什麼工作:

import urllib 
html = urllib.urlopen("http://pythonscraping.com/pages/page1.html") 
print(html.read()) 

我真的想了解發生了什麼,因爲我不希望我的Canopy python腳本在Canopy之外運行時失敗。此外,Canopy方法似乎與我讀過的文檔不一致......我剛剛試用了&錯誤。

回答

2

urllib.request是一個只存在於Python 3中的模塊。Enthought Canopy Distribution仍然附帶Python 2.7版本(2.7.10截至當前版本1.6.2)。

在Python 2.x中,可以選擇使用urlliburllib2,其在頂部電平(例如urllib.urlopen而非urllib.request.urlopen)暴露像urlopen功能的選擇。

如果你希望你的腳本能夠通過任意的Python 3.x或在Enthought雨棚的Python發行運行,那麼有兩種可能的解決方案:

  1. 使用requests - 這通常是推薦的圖書館用於在Python中與HTTP進行交互。這是一個第三方模塊,您可以使用標準pipeasy_install或從Canopy Package Index進行安裝。

    你的等效代碼將類似於:

    # This allows you to use the print() function inside Python 2.x 
    from __future__ import print_function 
    import requests 
    
    response = requests.get("http://pythonscraping.com/pages/page1.html") 
    print(response.text) 
    
  2. 使用條件進口的需要,無論版本的當前功能帶來。這只是使用Python的內置功能,並不需要第三方庫。然後

    您的代碼將類似於:

    # This allows you to use the print() function inside Python 2.x 
    from __future__ import print_function 
    import sys 
    
    try: 
        # Try importing Python 3's urllib.request first. 
        from urllib.request import urlopen 
    except ImportError: 
        # Looks like we're running Python 2.something. 
        from urllib import urlopen 
    
    response = urlopen("http://pythonscraping.com/pages/page1.html") 
    
    # urllib.urlopen's response object is different based 
    # on Python version. 
    if sys.version_info[0] < 3: 
        print(response.read()) 
    else: 
        # Python 3's urllib responses return the 
        # stream as a byte-stream, and it's up to you 
        # to properly set the encoding of the stream. This 
        # block just checks if the stream has a content-type set 
        # and if not, it defaults to just using utf-8 
        encoding = response.headers.get_content_charset() 
        if not encoding: 
         encoding = 'utf-8' 
        print(response.read().decode(encoding)) 
    
+0

工作就像一個魅力。重新考慮我現在使用Canopy!有關用於Python 3.x的最佳IDE的任何建議? –

+0

@ A.Gani - 我在vim或SublimeText中編寫我所有的Python,所以我對其他任何IDE都不太熟悉。不過,很多人都喜歡PyCharm。 – birryree