📜  在PycURL和Python中使用cURL

📅  最后修改于: 2020-09-03 04:43:41             🧑  作者: Mango

介绍

在本教程中,我们将学习如何使用PycURL,它是Python中cURL库的接口。cURL是一种用于与服务器之间进行数据传输以及进行各种类型的数据请求的工具。PycURL非常适合测试REST API,下载文件等。一些开发人员更喜欢使用Postman来测试API,但是PycURL是另一个合适的选择,因为它支持多种协议,例如FILE,FTPS,HTTPS,IMAP,POP3,SMTP,SCP,SMB等。此外,PycURL在很多情况下派上用场需要并发,快速和可靠的连接。

如上所述,PycURL是Python中libcURL库的接口;因此PycURL继承了libcURL的所有功能。PycURL速度非常快(众所周知,它比Requests快得多,Requests是HTTP请求的Python库),具有多协议支持,并且还包含用于支持网络操作的套接字。

先决条件

在继续本教程之前,请注意,有一些先决条件。您应该对Python的语法有基本的了解,并且/或者至少具有某种其他语言的初学者级编程经验。此外,您应该对通用网络概念(如协议及其类型)以及客户端-服务器通信模式有很好的了解。熟悉这些概念对于理解PycURL库至关重要。

安装

对于所有操作系统,PycURL的安装过程都非常简单明了。您只需要在系统上安装libcURL即可使用PycURL。

Mac / Linux作业系统

对于Mac OS和Linux,PycURL安装是最简单的,因为它没有依赖关系,并且默认情况下安装libcURL。只需在终端中运行以下命令,即可完成安装:

通过pip安装 
$ pip install pycurl 
通过easy_install安装
$ easy_install pycurl

Windows操作系统

但是,对于Windows,必须先安装一些依赖项,然后才能在程序中使用PyCURL。如果您使用的是Python的正式发行版(即您已经从官方网站https://www.python.org下载了Python版本)以及pip,则只需在命令行中运行以下命令,然后安装将完成:

$ pip install pycurl

如果您不使用pip,则可以在PycURL Windows上使用EXE和MSI安装程序。您可以像其他任何应用程序一样直接从那里下载并安装它们。

基本代码示例

在本节中,我们将覆盖一些PycURL编码示例,这些示例演示了接口的不同功能。

如简介部分所述,PycURL支持许多协议,并具有许多复杂的功能。但是,在我们的示例中,我们将与HTTP协议一起使用HTTP最常用的方法(GET,POST,PUT和DELETE)来测试REST API,以及其他一些示例。我们将编写在Python 3中声明它们的语法,并解释它们的作用。

因此,让我们开始吧!

示例1:发送HTTP GET请求

PycURL的简单网络操作是使用其URL从给定服务器检索信息。这被称为GET请求,因为它用于get网络资源。

通过导入BytesIO模块并创建其对象,可以使用PycURL执行简单的GET请求。创建CURL对象以通过URL传输数据和文件。

使用设置所需的网址setopt(),该功能用作setopt(option, value)。所述option参数指定选项来设置,例如URLWRITEDATA等等,和value参数指定给该特定选项的值。

然后将从设置的URL中检索的数据以字节的形式写入BytesIO对象。然后使用该getvalue()函数从BytesIO对象中读取字节,然后将其解码以将HTML打印到控制台。

这是如何执行此操作的示例: 

import pycurl
from io import BytesIO 

b_obj = BytesIO() 
crl = pycurl.Curl() 

# Set URL value
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')

# Write bytes that are utf-8 encoded
crl.setopt(crl.WRITEDATA, b_obj)

# Perform a file transfer 
crl.perform() 

# End curl session
crl.close()

# Get the content stored in the BytesIO object (in byte characters) 
get_body = b_obj.getvalue()

# Decode the bytes stored in get_body to HTML and print the result 
print('Output of GET request:\n%s' % get_body.decode('utf8')) 

输出: 

Output of GET request:








BeginnersGuide - Python Wiki



.
.
.

示例2:检查GET响应头

您还可以借助PycURL检索网站的响应标头。可以出于多种原因检查响应头,例如,找出随响应一起发送了哪种编码,以及是否根据服务器提供的编码。

在我们的示例中,我们将仅检查响应头以找出各种属性名称及其对应的值。

为了检查响应头,我们首先需要提取它们,我们使用HEADERFUNCTION选项进行提取,并使用自定义函数显示它们(display_header()在这种情况下)。

我们提供要检查其响应标题的站点的URL;HEADERFUNCTION将响应头发送到display_header()适当格式化的函数。根据指定的标准对响应头进行解码,并将其分为相应的名称和值。名称和值之间的空格被去除,然后将它们转换为小写字母。

然后将响应头写入BytesIO对象,传输到请求者,最后以正确的格式显示。

from io import BytesIO
import pycurl

headers = {}

def display_header(header_line):
    header_line = header_line.decode('iso-8859-1')

    # Ignore all lines without a colon
    if ':' not in header_line:
        return

    # Break the header line into header name and value
    h_name, h_value = header_line.split(':', 1)

    # Remove whitespace that may be present
    h_name = h_name.strip()
    h_value = h_value.strip()
    h_name = h_name.lower() # Convert header names to lowercase
    headers[h_name] = h_value # Header name and value.

def main():
    print('**Using PycURL to get Twitter Headers**')
    b_obj = BytesIO()
    crl = pycurl.Curl()
    crl.setopt(crl.URL, 'https://twitter.com')
    crl.setopt(crl.HEADERFUNCTION, display_header)
    crl.setopt(crl.WRITEDATA, b_obj)
    crl.perform()
    print('Header values:-')
    print(headers)
    print('-' * 20)
    
main()

输出:

**Using PycURL to get Twitter Headers**
Header values:-
{'cache-control': 'no-cache, no-store, must-revalidate, pre-check=0, post-check=0', 'content-length': '303055', 'content-type': 'text/html;charset=utf-8', 'date': 'Wed, 23 Oct 2019 13:54:11 GMT', 'expires': 'Tue, 31 Mar 1981 05:00:00 GMT', 'last-modified': 'Wed, 23 Oct 2019 13:54:11 GMT', 'pragma': 'no-cache', 'server': 'tsa_a', 'set-cookie': 'ct0=ec07cd52736f70d5f481369c1d762d56; Max-Age=21600; Expires=Wed, 23 Oct 2019 19:54:11 GMT; Path=/; Domain=.twitter.com; Secure', 'status': '200 OK', 'strict-transport-security': 'max-age=631138519', 'x-connection-hash': 'ae7a9e8961269f00e5bde67a209e515f', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'x-response-time': '26', 'x-transaction': '00fc9f4a008dc512', 'x-twitter-response-tags': 'BouncerCompliant', 'x-ua-compatible': 'IE=edge,chrome=1', 'x-xss-protection': '0'}
--------------------

如果我们有多个具有相同名称的标头,则只会存储最后一个标头值。要将所有值存储在多值标头中,我们可以使用以下代码:

if h_name in headers:
    if isinstance(headers[h_name], list):
        headers[name].append(h_value)
    else:
        headers[h_name] = [headers[h_name], h_value]
else:
    headers[h_name] = h_value

示例3:通过HTTP POST发送表单数据

POST请求是通过将数据封装在HTTP请求的主体中来将数据发送到Web服务器的请求。当您上传文件或提交表单时,基本上是在向指定的服务器发送POST请求。

可以通过使用PycURL来执行POST请求,方法是首先设置URL以通过该setopt功能将表单数据发送到该URL 。首先,要以字典的形式(以键值对的形式)存储要提交的数据,然后使用模块中的urlencode功能对其进行URL编码urllib.parse

我们POSTFIELDS在发送表单数据时使用该选项,因为该选项会自动将HTTP请求方法设置为POST,并且pf也会处理我们的数据。

from urllib.parse import urlencode
import pycurl

crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
data = {'field': 'value'}
pf = urlencode(data)

# Sets request method to POST,
# Content-Type header to application/x-www-form-urlencoded
# and data to send in request body.
crl.setopt(crl.POSTFIELDS, pf)
crl.perform()
crl.close()

注意:如果您想指定其他请求方法,则可以使用CUSTOMREQUEST选项来指定。只需在下面的空的反向逗号中输入您选择的请求方法的名称即可crl.CUSTOMREQUEST

crl.setopt(crl.CUSTOMREQUEST, '')

示例4:使用分段POST上传文件

您可以通过多种方式复制使用PycURL以HTML格式上传文件的方式:

  1. 如果要通过POST请求发送的数据在系统上的文件中,则需要首先设置要发送数据的URL。然后,将您的请求方法指定为,HTTPPOST并使用该fileupload选项上传所需文件的内容。
    import pycurl
    
    crl = pycurl.Curl()
    crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
    
    crl.setopt(crl.HTTPPOST, [
        ('fileupload', (
            # Upload the contents of the file
            crl.FORM_FILE, './my-resume.doc',
        )),
    ])
    crl.perform()
    crl.close()

    注意:如果要更改文件的名称和/或内容类型,可以通过对上面的代码进行一些修改来做到:

    crl.setopt(crl.HTTPPOST, [
        ('fileupload', (
            # Upload the contents of this file
            crl.FORM_FILE, './my-resume.doc',
            # Specify a file name of your choice
            crl.FORM_FILENAME, 'updated-resume.doc',
            # Specify a different content type of upload
            crl.FORM_CONTENTTYPE, 'application/msword',
        )),
    ])
  2. 对于内存中的文件数据,在POST请求的实现中所有不同的是FORM_BUFFERFORM_BUFFERPTRFORM_FILE因为它们直接从内存中获取要发布的数据。 
    import pycurl
    
    crl = pycurl.Curl()
    crl.setopt(crl.URL, 'https://www.code-learner.com/post/')
    
    crl.setopt(crl.HTTPPOST, [
        ('fileupload', (
            crl.FORM_BUFFER, 'contact-info.txt',
            crl.FORM_BUFFERPTR, 'You can reach me at billy@example.com',
        )),
    ])
    
    crl.perform()
    crl.close()

     

示例5:使用HTTP PUT上传文件

PUT请求本质上与POST请求类似,不同之处在于可以将PUT请求上传到请求正文中。当您知道要创建或覆盖的对象的URL时,可以使用PUT请求。基本上,PUT将目标URL当前存在的任何内容替换为其他内容。

如果要上载的所需数据位于物理文件中,则首先需要设置目标URL,然后上载文件并打开它。在cURL对象使用文件时,保持文件打开很重要。然后使用从文件中读取数据READDATA

最后,使用该perform功能执行文件传输(上传),然后结束cURL会话。最后,关闭最初为CURL对象打开的文件。

import pycurl

crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')

dat_file = open('data.txt')

crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, dat_file)

crl.perform()
crl.close()
dat_file.close()

如果文件数据位于缓冲区中,则PycURL实现与上载位于物理文件中的数据的实现几乎相同,只是稍作修改。BytesIO对象使用指定的标准对数据进行编码。这是因为READDATA需要类似IO的对象,并且编码数据对于Python 3是必不可少的。该编码数据存储在缓冲区中,然后读取该缓冲区。执行数据上载,完成上载后,cURL会话结束。

import pycurl
crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://www.code-learner.com/post/')

data = '{"person":{"name":"billy","email":"billy@example.com"}}'
buffer = BytesIO(data.encode('utf-8'))

crl.setopt(crl.UPLOAD, 1)
crl.setopt(crl.READDATA, buffer)

crl.perform()
crl.close()

示例6:发送HTTP DELETE请求

另一个重要且使用最多的HTTP方法是DELETE。DELETE方法请求服务器删除目标URL标识的资源。可以使用该CUSTOMREQUEST函数来实现,如下面的代码示例所示:

import pycurl

crl = pycurl.Curl()
crl.setopt(crl.URL, "http://api.example.com/user/148951")
crl.setopt(crl.CUSTOMREQUEST, "DELETE")
crl.perform()
crl.close()

示例7:写入文件

PycURL也可以用于保存对文件的响应。我们使用该open函数打开文件,并将响应作为文件对象返回。该open函数的形式为:open(file, mode)。该file参数表示要打开的文件的路径和名称,并mode表示要打开文件的方式。在我们的示例中,以二进制模式(即wb)打开文件很重要,以避免编码和解码响应。

import pycurl

file = open('pycurl.md','wb')

crl = pycurl.Curl()
crl.setopt(crl.URL, 'https://wiki.python.org/moin/BeginnersGuide')
crl.setopt(crl.WRITEDATA, file)
crl.perform()
crl.close()

结论

在本教程中,我们了解了Python中的PycURL接口。我们首先讨论PycURL的一些常规功能及其与Python中libcURL库的相关性。然后,我们看到了PycURL在不同操作系统上的安装过程。

最后,我们看了一些PycURL的一般示例,这些示例演示了PycURL提供的各种功能,例如HTTP GET,POST,PUT和DELETE方法。学习完本教程之后,您应该能够轻松地在Python程序中获取由URL标识的对象。