在Python3中的urllib与urllib.request - Enthought Canopy

时间:2016-01-24 15:09:57

标签: python urllib canopy

在尝试加载和利用urllib和/或urllib.request时,在Enthought Canopy与命令行中获得奇怪的区别

这就是我的意思。我在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 

当Canopy尝试执行from urllib.request import urlopen

在Canopy内部,这是有效的:

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

我真的很想了解发生了什么,因为当我在Canopy之外运行时,我不希望我的Canopy python脚本失败。此外,Canopy方法似乎与我读过的文档不一致......我只是通过试用和实验;错误。

1 个答案:

答案 0 :(得分:2)

urllib.request是一个仅存在于Python 3中的模块.Enthought Canopy Distribution仍然附带一个Python 2.7版本(2.7.10,截至当前版本1.6.2)。

在Python 2.x中,您可以选择使用urlliburllib2,在顶层公开urlopen等函数(例如urllib.urlopen而不是urllib.request.urlopen pip)。

如果您希望脚本能够通过Python 3.x或Enthought Canopy的Python发行版运行,那么有两种可能的解决方案:

  1. 使用requests - 这通常是推荐用于在Python中与HTTP交互的库。这是第三方模块,您可以使用标准easy_install# 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) Canopy Package Index进行安装。

    您的等效代码类似于:

    # 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))
    
  2. 使用条件导入来引入您需要的当前功能,无论版本如何。这只是使用Python的内置功能,不需要第三方库。

    您的代码看起来类似于:

    UPDATE Article
    SET Revisions = LEAST(Revisions + 1, 100)
    where Id = @p0