您的位置:

python请求中的curl(python接收HTTP请求)

本文目录一览:

python 执行curl系统命令为什么会返回进度条

试试用os.popen()来执行。 popen()可以返回执行结果信息。 ret_msg = os.popen(command) 通过python执行系统命令时,最要注意路径问题。不论是文件还是目录一定要写全路径,不要用相对路径。

Curl.是什么意思

cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。

cURL支持的通信协议有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。

扩展资料:

一、PHP cURL 函数

PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。libcurl支持http、https、ftp、gopher、telnet、dict、file和ldap协议。

libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、 FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。

二、表单提交

通过Form表单,可以将Web页面的表单数据提交到服务端。提交表单时,可以使用GET或POST提交方法。curl同样支持表单数据提交,也可以使用GET或POST提交方法。

1、GET数据提交

当全用GET表单数据提交时,提交数据会被附加到请求URL的后面。类型如下:

$ curl '//itbilu.com/?keyword=linuxpage=3'

使用curl进行GET数据提交时,也可以直接把提交数据添加到URL后面:

curl ;page=3

2、POST数据提交

curl使用POST提交表单数据时,除了-X参数指定请求方法外,还要使用--data参数添加提交数据:

$ curl -X POST --data 'keyword=linux' itbilu.com

参考资料来源:百度百科-curl

如何利用cURL和python对服务端和web端进行接口测试

工具描述

cURL是利用URL语法在命令行方式下工作的文件传输工具,是开源爱好者编写维护的免费工具,支持包括Windows、Linux、Mac等数十个操作系统,最新版本为7.27.0,但是我推荐大家使用7.26.0,从这里可以下载7.26.0版本。

以下是官方介绍的翻译:

cURL是一个使用URL语法来传输数据的命令行工具,支持

DICT,FILE,FTP,FTPS,GOPHER,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP3S,RTMP,RTSP,SCP,SFTP,SMTP,SMTPS,Telnet

和TFTP。 cURL支持SSL证书,HTTP POST,HTTP

PUT,FTP上传,HTTP基础表单上传,代理,cookies,用户+密码身份验证(Basic, Digest, NTLM,

Negotiate, kerberos...),恢复文件传输,隧道代理等等。

Python是一种面向对象、直译式计算机程序设计语言,由Guido van Rossum于1989年底发明,它的强大和易用就无需多做说明了,在web开发中或者对开发速度要求较高的开发中应用十分广,不过因为属于脚本类语言,它的性能始终比不上C++、C等语言。

本文主要利用实例说明这两款工具的在测试中的部分用途,更多用法留待大家继续探索。

应用场景

使用cURL模拟客户端对服务端进行查询

在进行接口测试时,应该先找开发人员提供接口列表和对应参数,这样测试的时候就可以验证测试方法是否正确,不过如果可以用浏览器模拟操作的话,也可以自己先试试的,后面的例子会提到。

首先使用客户端访问需要测试的服务端接口,用wireshark抓包结果如下:

把查询字符串以multipart方式post数据到服务器的file_health_info.php接口。

Tips:

Windows版的cURL不像Linux或者Mac一样属于系统自带工具,需要下载,如果要在命令提示符下使用就需要跳转到工具所在目录下才能运

行,十分麻烦,我们可以直接把这个工具文件放到Windows目录下,这样无论在哪个目录都可以直接使用“curl”命令运行工具了。

cURL默认就是以post方式发送数据的,所以只需要加入multipart方式就可以了,-F在cURL帮助中的解释是:

-F, --form CONTENT Specify HTTP multipart POST data (H)

--form-string STRING Specify HTTP multipart POST data (H)

--ftp-account DATA Account data string (F)

--ftp-alternative-to-user COMMAND String to replace "USER [name]" (F)

--ftp-create-dirs Create the remote dirs if not present (F)

--ftp-method [MULTICWD/NOCWD/SINGLECWD] Control CWD usage (F)

--ftp-pasv Use PASV/EPSV instead of PORT (F)

Specify HTTP multipart POST data正好满足我们的要求,所以模拟的语句是:

curl -F "newmd5=3bcad21af5f17c1fbff419137297c942###25016566###d:\test.exe###1###"

后面的都是参数,测试前就要找开发确认好。

不过因为服务端支持以gzip方式返回数据,所以我们还可以在请求中加入—compressed参数,即是:

curl --compressed -F "newmd5=3bcad21af5f17c1fbff419137297c942###25016566###d:\test.exe###1###"

为了更好判断服务端接口是否正常,除了对返回数据进行判断外,我们还需要对服务端返回的数据包头进行解析,所以还可以在cURL请求中加入-i参数,最终这个测试语句就变为:

curl –i --compressed -F "newmd5=3bcad21af5f17c1fbff419137297c942###25016566###d:\test.exe###1###"

模拟完成后就要考虑判断返回值的事了,我们首先在命令提示符下运行这个语句,看看返回值。

运行以上命令后,返回的数据如下:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK

Date: Fri, 24 Aug 2012 07:47:45 GMT

Content-Type: application/xml

Transfer-Encoding: chunked

Connection: keep-alive

Server: 360 web server

Content-Encoding: gzip

?xml version="1.0" encoding="GBK" ?

ret

retinfo code="0" msg="Operation success" total="1" success="1" empty="0"

cost="999.92752075195"/

softs

soft

md53bcad21af5f17c1fbff419137297c942/md5

sha1/sha1

level4040/level

e_level40.3/e_level

size/size

soft_name![CDATA[]] /soft_name

describ![CDATA[]]/describ

file_desc![CDATA[]]/file_desc

upload0/upload

attr_upload2/attr_upload

class![CDATA[private]]/class

malware![CDATA[cloud.virus]]/malware

is_sys_file0/is_sys_file

is_rep0/is_rep

age0/age

pop0/pop

/soft

/softs

/ret

数据包包头是常见的,一般来说,我们只要判断包头中含有“HTTP/1.1 200

OK”就可以确定服务端正常返回了数据。另外从内容可以看到这是一个xml格式的数据包,我们只需要判断是否存在关键的字段即可,比

如level,确定这些之后我们就可以在python中添加如下案例代码了:

首先运行指定的curl命令:

response = os.popen(‘‘‘curl -i --compressed -F "newmd5=3bcad21af5f17c1fbff419137297c942###25016566###d:\test.exe###1###"

然后判断返回值中是否存在我们想要的字段:

self.assertNotEqual(response.find(‘HTTP/1.1 200 OK‘),-1)

self.assertNotEqual(response.find(‘level‘),-1)

上面的内容看起来差不多可以了,但实际还不够严谨,因为服务端返回的这些数据是从数据库中获取的,所以我们还需要查询数据库获取指定值,判断是否和数据包中的一致,比如level:

首先使用python登录数据库服务器:

conn = MySQLdb.connect(host=‘172.22.54.31‘, user=‘user‘,passwd=‘test321‘,db=‘cloud‘)

cursor = conn.cursor()

count = cursor.execute(‘SELECT plevel FROM file where md5="3bcad21af5f17c1fbff419137297c942"‘)

result = cursor.fetchone()

然后判断返回值中的level是否数据库中的值:

self.assertNotEqual(response.find(‘‘‘level%s/level‘‘‘%result[0]),-1)

测试时除了使用cURL等工具进行模拟,还可以自己用python或其他语言写代码进行post数据,不过当时简单起见所以就选择了用cURL测试。

使用cURL模拟控制台登录

说到模拟登录或者模拟点击,很多同学可能直接联想到QTP等模拟界面操作的工具,事实上这种工具有一个很大的弊端是太依赖控件,如果界面控件变了,

那么可能整个脚本就无效了,现在的程序设计都倾向界面逻辑分离,这样修改界面时就不会动到底下的功能接口,开发人员可以随时修改界面控件,如果还是采取

QTP等模拟点击的方法测试,结果可能是事倍功半的,如果测试时直接点用接口就可以避免这种问题。

下面的例子是模拟控制台登录的,登录URL为:

,首先使用浏览器登录一次,看看实际效果如何。

Tips:

测试php或其他web程序时建议使用chrome,因为它自带的Developer

Tools十分好用,当然firefox或者IE9也有类似的工具,看个人习惯吧。按F12打开工具,选择Network标签页,然后输入用户名、密码点

击登录,这时Network下方会显示登录过程中浏览器想控制台请求的所有数据,包括请求类型、表单数据等,这些是我们模拟操作的数据来源。

从上图可以获取几个重点信息:请求URL、请求类型、数据类型、数据内容、并且支持gzip压缩等。我们用curl模拟如下:

curl -i --compressed -d “username=admin” -d “userpass=admin”

使用-i和—compressed的原因再上一个例子已经说了,这里不再赘述,重点是后面的-d,它在官方帮助的解释是:

-d, --data DATA HTTP POST data (H)

--data-ascii DATA HTTP POST ASCII data (H)

--data-binary DATA HTTP POST binary data (H)

--data-urlencode DATA HTTP POST data url encoded (H)

--delegation STRING GSS-API delegation permission

--digest Use HTTP Digest Authentication (H)

--disable-eprt Inhibit using EPRT or LPRT (F)

--disable-epsv Inhibit using EPSV (F)

而我们从Developer Tools返回的数据已经知道,返回数据的格式是

“application/x-www-form-urlencoded”,所以很明显需要使用-d的HTTP POST data url encoded特性。不过格式中还有关键字form,莫非也支持-F参数登录,试试:

curl -i --compressed -F “username=admin” -F “userpass=admin”,果然成功,呵呵~

也许有同学有疑问,为何不模拟warnsetup、refer,这是因为测试时发现登录界面只需要用户名和密码就够了,refer 用于记录来源网页,在这里用处不大,warnsetup只是用于验证登录码的,这个已经去掉了。

接下来要验证数据,我们在命令提示符中运行上面的命令,返回结果如下:

HTTP/1.1 302 Moved Temporarily

Date: Fri, 24 Aug 2012 08:29:07 GMT

Content-Type: text/html

Transfer-Encoding: chunked

Connection: keep-alive

X-Powered-By: PHP/5.4.3

Set-Cookie: PHPSESSID=4711d2365de9aaaca0c28b1ca52183f0; path=/

Expires: Thu, 19 Nov 1981 08:52:00 GMT

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Pragma: no-cache

Set-Cookie: PHPSESSID=81d4bb65e888c1b6347120641eb4798b; path=/

Location: ./index.php

Server: 360 web server

很奇怪吧,乍一看控制台没有返回任何有用信息,不过里面那句HTTP/1.1 302 Moved

Temporarily是不是特别眼熟?这个特殊的302(表示http重定向)正是我们在Developer

Tools看到的状态值,看到这个已经可以80%确定我们登录已经成功了,更重要的是返回包中的内容:Location:

./index.php,这说明控制台已经通知请求端跳转到index.php,如果登录失败控制台会继续停留在当前登录界面的,我们只需要修改curl

语句中的用户名或者密码就知道了,这种情况下返回包就是登录界面的php源码,这里不再赘述。

使用cURL以get方式测试控制台搜索接口

测试方法同上面差不多,首先使用chrome打开控制台进入对应页面,在搜索框中输入“test.exe”,点击搜索,使用developer tools抓包,内容如下:

cURL模拟get方式发送数据的参数是-G,了解这个后面要模拟就很简单了:

curl -i --compressed -G “;filename=59c7dd2eafdbe86b2e23bcdabb575448bg=0lm=19

其中每个参数的含义要分别了解:filename表示输入的关键字,bg表示数据库第一行,lm表示共显示19行数据。这个接口返回的数据如下:

{"rows":[{"level":"10","plevel":"10","id":"20","md5":"59c7dd2eafdbe86b2e23bcdabb575448","soft_name":"","soft_desc":"","file_desc":"QVBJIFRyYWNpbmcgWDg2IEhvb2sgRW5naW5l","is_sys_file":"127","size":"41984","is_rep":"0","file_name":"apihex86.d

ll","file_version":"6.1.7600.16385","product_version":"6.1.7600.16385","copyright":"\u00a9 Microsoft Corporation. All rights reserved.","lang":"0","org_name":"YXBpaGV4ODYuZGxs","sign_name":"TWljcm9zb2Z0IFdpbmRvd3M=","company_name":"Microsof

t Corporation","update_time":"2012-07-31 18:14:27","create_time":"2012-07-31 18:14:27","creator_mid":"15be5b7dce003cdc2c1d1448afcf6cf0"}],"count":"1"}

分别是文件属性和文件信息,这涉及到两个数据库表,所以验证数据需要用python从两张表中获取对应信息。

从第一张表获取文件属性,比如只获取plevel:

SELECT plevel FROM `file` where md5="59c7dd2eafdbe86b2e23bcdabb575448"

从第二张表获取文件信息,比如只获取company_name:

SELECT company_name FROM file_info where md5="59c7dd2eafdbe86b2e23bcdabb575448"

Python代码如下:

conn = MySQLdb.connect(host=‘%s‘% self.host, user=‘user‘,passwd=‘test321‘,db=‘cloud‘)

cursor = conn.cursor()

count = cursor.execute(‘SELECT plevel FROM `file` where md5="111111932490c813bf5ea9d8aa6fa60c"‘)

result = cursor.fetchone()

self.assertNotEqual(response.find(str(result[0])),-1)

count = cursor.execute(‘SELECT company_name FROM file_info where md5="111111932490c813bf5ea9d8aa6fa60c"‘)

result1 = cursor.fetchone()

self.assertNotEqual(response.find(result1[0]),-1)

当然严谨的测试案例是每一个属性字段都需要进行查找和匹配,这里就不再赘述了。