Python中哪个更好: urllib2、PycURL还是mechanize?

72

好的,所以我需要使用Python下载一些网页,并快速调查了我的选择。

与Python一起包含:

urllib - 我认为我应该使用urllib2。urllib没有cookie支持,仅支持HTTP / FTP /本地文件(无SSL)

urllib2 -完整的HTTP / FTP客户端,支持大多数所需功能,如cookies,不支持所有HTTP动词(仅限GET和POST,没有TRACE等)

全功能:

mechanize - 可以使用/保存Firefox / IE cookies,执行操作,如跟随第二个链接,处于积极维护状态(0.2.5在2011年3月发布)

PycURL - 支持curl支持的所有内容(FTP,FTPS,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP),坏消息:自2008年9月9日以来未更新(7.19.0)

新可能性:

urllib3 - 支持连接重用/池和文件发布

已弃用(又名请改用urllib / urllib2):

httplib - 仅限HTTP / HTTPS(无FTP)

httplib2 - 仅限HTTP / HTTPS(无FTP)

我注意到的第一件事是,urllib / urllib2 / PycURL / mechanize都是相当成熟的解决方案,运作良好。mechanize和PycURL附带在许多Linux发行版(例如Fedora 13)和BSD上,因此通常安装不是问题(所以这很好)。

urllib2看起来不错,但我想知道为什么PycURL和mechanize都很受欢迎,我是否漏掉了什么(即如果我使用urllib2,是否会陷入某些困境?)。我真的很想得到关于这些工具的优缺点反馈,以便我可以为自己做出最好的选择。

编辑:添加了关于urllib2中动词支持的说明。


3
"Best" 意味着什么?相对于什么最好?是最快?最大?最好的 Cookie 使用?你需要做什么? - S.Lott
1
httplib并非“已弃用”。它是urllib2构建在其上的较低级别模块。您可以直接使用它,但通过urllib2更容易。 - Corey Goldberg
1
就像Corey所说的那样,例如urllib3是在httplib之上的一层。此外,httplib2并没有被弃用 - 事实上,它比urllib2更新,并解决了诸如连接重用(与urllib3相同)之类的问题。 - Yang
12
有一个名为 requests 的新库。请参见 http://docs.python-requests.org/en/latest/index.html。 - ustun
1
支持 @ustun 的观点:使用 requests。 - hughdbrown
8个回答

45
我认为这次在pycon 2009的演讲中,有你所寻找的答案(Asheesh Laroia在此方面有丰富的经验)。他指出了大部分列表中的优点和缺点。

来自PYCON 2009日程安排:

你是否遇到需要提取数据的网站?如果您可以编程地输入数据到Web应用程序,即使这些应用程序针对机器人进行了干扰,您的生活会变得更简单吗?我们将讨论Web抓取的基础知识,然后深入研究不同方法的细节以及它们最适用的地方。您将了解何时应用不同的工具,并了解我在电子前沿基金会项目中掌握的屏幕抓取的“重锤”。参与者应尽可能带上笔记本电脑,以尝试我们讨论的示例并选择性地记录笔记。 更新:Asheesh Laroia已经为pycon 2010更新了他的演示文稿。
  • PyCon 2010: Scrape the Web: Strategies for programming websites that don't expected it

    * My motto: "The website is the API."
    * Choosing a parser: BeautifulSoup, lxml, HTMLParse, and html5lib.
    * Extracting information, even in the face of bad HTML: Regular expressions, BeautifulSoup, SAX, and XPath.
    * Automatic template reverse-engineering tools.
    * Submitting to forms.
    * Playing with XML-RPC
    * DO NOT BECOME AN EVIL COMMENT SPAMMER.
    * Countermeasures, and circumventing them:
          o IP address limits
          o Hidden form fields
          o User-agent detection
          o JavaScript
          o CAPTCHAs 
    * Plenty of full source code to working examples:
          o Submitting to forms for text-to-speech.
          o Downloading music from web stores.
          o Automating Firefox with Selenium RC to navigate a pure-JavaScript service. 
    * Q&A; and workshopping
    * Use your power for good, not evil. 
    

更新2:

PyCon US 2012 - 网络爬虫: 可靠高效地从不预期(不欢迎)的页面中提取数据

令人兴奋的信息被困在网页和HTML表单中。在本教程中,您将学习如何解析这些页面,并在何时应用先进技术,以使采集更快速、更稳定。我们将介绍使用Twisted、gevent等并行下载、分析SSL背后的站点、使用Selenium推动JavaScript的站点以及避开常见的反采集技术。


对于那些没有时间听完整个演讲的人来说,总结该演讲建议的两三句话会很好。 :-) - Brandon Rhodes

39

Python requests也是处理HTTP请求的不错选择。我个人认为它有更好的API,以下是官方文档中的一个示例http请求:

>>> r = requests.get('https://api.github.com', auth=('user', 'pass'))
>>> r.status_code
204
>>> r.headers['content-type']
'application/json'
>>> r.content
...

requests 内部使用 urllib3。 - Yuvaraj Loganathan

35
  • urllib2被发现在Python的每个安装包中都存在,因此是一个很好的起点。
  • PycURL对于已经习惯使用libcurl的人非常有用,它公开了更多HTTP底层详细信息,并且获得了应用于libcurl的任何修复或改进。
  • mechanize类似于浏览器,用于持续驱动连接。

并不是某个工具比另一个工具更好,而是选择适当的工具来完成工作的问题。


我在我的Python应用程序中实现了httplib2。httplib2支持NTLM吗?如果不支持,我该怎么做才能进行NTLM身份验证?注意:我发现httplib2不支持NTLM。 - Ayyappan Anbalagan
2
@Ayyappan urllib3通过contrib子模块支持NTLM:urllib3/contrib/ntlmpool.py - shazow

3
要“获取一些网页”,请使用requests
来自http://docs.python-requests.org/en/latest/
Python的标准urllib2模块提供了大部分您需要的HTTP功能,但该API已经完全失效。它是为不同的时间和不同的网络构建的。即使是最简单的任务也需要大量的工作(甚至是方法重写)。
事情不应该是这样的,在Python中不应该如此。
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'private_gists': 419, u'total_private_repos': 77, ...}

2
不要担心“最后更新时间”。在过去的几年中,HTTP没有太多变化 ;) urllib2是最好的选择(因为它是内置的),如果你需要来自Firefox的cookies,则可以切换到mechanize。mechanize可以用作urllib2的替代品 - 它们具有类似的方法等。使用Firefox cookies意味着您可以使用个人登录凭据从网站(例如StackOverflow)获取信息。只需对请求的数量负责(否则您将被阻止)。
PycURL适用于需要libcurl中所有低级功能的人。我建议先尝试其他库。

1
requests在存储cookies方面也非常有用。使用requests,您可以创建一个新的会话,然后调用sessionName.get()而不是requests.get()。这样,cookies将被存储在您的会话中。例如,一旦您使用会话登录到网站,您就可以使用该会话作为已登录用户执行其他http请求。 - hostingutilities.com

2

Urllib2只支持HTTP的GET和POST请求,虽然可能有一些变通的方法,但如果您的应用程序依赖于其他HTTP动词,您可能更喜欢使用另一个模块。


2
不是真的。请参见Python - 使用urllib2进行HEAD请求 - Piotr Dobrogost
@Piotr Dobrogost。仍然非常正确。在您可以使用urllib2.urlopen生成“HEAD”请求之前,它是不受支持的。创建自定义子类!= HEAD支持。我可以创建一个“int”子类,它会生成HTML,但从来没有说Python int可以生成HTML这样的语义上讲得通。 - mikerobi
直到您可以使用urllib2.urlopen生成HEAD请求,否则它是不受支持的。您为什么这样认为?创建自定义子类!= HEAD支持。urllib2缺少哪个部分的HEAD支持? - Piotr Dobrogost
1
@Piotr Dobrogost,我认为是因为API不支持它。如果您可以向我指出ullib2.urlopen生成非GET或POST请求的示例,我将删除我的答案。 - mikerobi

1

每个能够处理HTTP的Python库都有其独特的优点。

使用最少量的功能来完成特定任务的库。

您的列表至少缺少urllib3 - 一个很棒的第三方HTTP库,它可以重用HTTP连接,从而大大加快了从同一站点检索多个URL的过程。


requests在内部使用urllib3。 - hostingutilities.com

1
请看一下Grab(http://grablib.org)。它是一个网络库,提供两个主要接口: 1)Grab用于创建网络请求和解析检索到的数据 2)Spider用于创建批量网站爬虫
在Grab的内部,使用了pycurl和lxml,但也可以使用其他网络传输方式(例如requests库)。但是,Requests传输方式尚未经过充分测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接