zoukankan      html  css  js  c++  java
  • perl6 HTTP::UserAgent (2)

    http://www.cnblogs.com/perl6/p/6911166.html

    之前这里有个小小例子, 这里只要是总结一下。

     

    HTTP::UserAgent包含了以下模块:

    ----------------------------------------------------------------------------------------------
    Module                 |Path-Name                    |File-ID
    ----------------------------------------------------------------------------------------------
    HTTP::Header           |lib/HTTP/Header.pm6          |A2B86332480F329B842FC2F3922B81A1F7B1D4E9
    HTTP::Cookie           |lib/HTTP/Cookie.pm6          |8BBC36DD2291BA0AA0055B55B7DE6FD9688D6C53
    HTTP::Message          |lib/HTTP/Message.pm6         |36AD1387CCFFA8C668215E08B003366DCB85A964
    HTTP::Cookies          |lib/HTTP/Cookies.pm6         |438D31E029F25512CB05696C78EE4AF41B40527A
    HTTP::Request          |lib/HTTP/Request.pm6         |458DA83ACB4B7B3BA98573502EB4879AC1D92194
    HTTP::Response         |lib/HTTP/Response.pm6        |992068840F9CBA1830BB4A29F4338946BABA70B5
    HTTP::MediaType        |lib/HTTP/MediaType.pm6       |6970F2A79AC4473EED61B71050458E5BFC9702F2
    HTTP::UserAgent        |lib/HTTP/UserAgent.pm6       |7789AD4CBAC37F02FE832B1C68B30593E2217384
    HTTP::Header::Field    |lib/HTTP/Header/Field.pm6    |FDBA1F1A4186FD9C0D675459CB6D40479BA7ADE5
    HTTP::Request::Common  |lib/HTTP/Request/Common.pm6  |9ED2E957313B252F4FFBF086D39C8918F6C7C4F0
    HTTP::UserAgent::Common|lib/HTTP/UserAgent/Common.pm6|ECD443F272FDD584E9EBA9449AA32E9C84C87F26
    ----------------------------------------------------------------------------------------------

     

    HTTP::UserAgent -> 创建一个浏览器($ua)

    HTTP::Cookies -> 设置COOKIE

    HTTP::Header -> 设置头部信息, 如User-Agent, Content-Type等

    HTTP::Request -> 设置一个请求, 比如POST/GET等

     

    我们先看一下数据包结构:

     

    上面一部分中的User-Agent/Accept等头部修息, 可以用 HTTP::Header 设置。

    Cookie 位置可以用 HTTP::Cookies 设置

    下面的POST发送过去的数据, 我们可以用 HTTP::UserAgent 发送或用HTTP::Request设置后再发送。

     

    我们先看一下HTTP::Cookies

    > my $c = HTTP::Cookies.new
    HTTP::Cookies.new(cookies => [], file => Any, autosave => 0)
    > $c
    HTTP::Cookies.new(cookies => [], file => Any, autosave => 0)
    >

     

    方法有如下几个:

    > $c.^methods
    (extract-cookies add-cookie-header save load clear-expired clear set-cookie push-cookie Str cookies
    file autosave)

    手动设置Cookie可以用 set-cookie 方法:

    $c.set-cookie('Set-Cookie:a=b');

    注意里面的 Set-Cookie字符串一定要有。

    my $cookies = HTTP::Cookies.new;
        $cookies.set-cookie('Set-Cookie: name1=value1; Secure');
        $cookies.set-cookie('Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT');
        $cookies.clear; # 清除cookie

     

     

    这就是 cookie 的设置。当然还有其他方法, 但个人觉得这个已经够用了。

     

    我们来看 HTTP::Request:

    > my $r = HTTP::Request.new;
    HTTP::Request.new(method => HTTP::Request::RequestMethod, url => Any, file => Any, uri => Any, host
    => Str, port => Int, scheme => Str, header => HTTP::Header.new(fields => []), content => Any, protoc
    ol => "HTTP/1.1", binary => Bool::False, text-types => Array[Str].new())
    >

    注意上面的 $r 对象, 它参数中包含有一个 header => HTTP::Header.new()对象, 所以我们很容易想到, 当我们创建 request 对象时, 可以设置 HTTP::Header 对象的属性值。

    至于 HTTP::Header 对象的方法, 我们一会再说。 先看看 request 对象的方法:

    > $r.^methods;
    (new set-method uri host port scheme add-cookies add-content add-form-data form-data make-boundary S
    tr parse method url file add-content remove-field content-encoding push-field protocol text-types in
    flate-content decoded-content AUTOGEN parse header charset is-text Str content new clear content-typ
    e media-type is-binary binary)
    >

     

    方法挺多, 这里只是说明几个常用的, 比如设置Cookie, 设置Header。

     

    0x1设置请求类型:

    my $req = HTTP::Request.new;
        $req.set-method: 'POST';

    你还可以设置成GET或HEAD之类的。

     

    0x2设置请求的URL:

    my $req = HTTP::Request.new;
        $req.uri: 'example.com';

     

    0x3设置Cookie:

    add-cookies(HTTP::Cookies $cookies)

    上面说过HTTP::Cookies的用法, 如果你设置了一个HTTP::Cookies对象, 这里直接导入就行:

    my $req = HTTP::Request.new;
    #my $c = HTTP::Cookies.new;
    #$c.set-cookie('Set-Cookie:user=root')
    $req.add-cookies($c)

     

    0x4设置POST参数:

    my %data = :what<php>;#post
    my $r = HTTP::Request.new;
    $r.set-method: 'POST';
    $r.add-form-data(%data);#添加post

     

    0X5设置 HTTP::Header:

    上面说到, 这个HTTP::Request对象的参数里包含了一个 header => HTTP::Header.new()。而且它有个方法叫header, 我们可以先看看这个header方法是什么东西:

    > my $r = HTTP::Request.new;
    HTTP::Request.new(method => HTTP::Request::RequestMethod, url => Any, file => Any, uri => Any, host
    => Str, port => Int, scheme => Str, header => HTTP::Header.new(fields => []), content => Any, protoc
    ol => "HTTP/1.1", binary => Bool::False, text-types => Array[Str].new())
    > $r.^methods;
    (new set-method uri host port scheme add-cookies add-content add-form-data form-data make-boundary S
    tr parse method url file add-content remove-field content-encoding push-field protocol text-types in
    flate-content decoded-content AUTOGEN parse header charset is-text Str content new clear content-typ
    e media-type is-binary binary)
    > my $r = HTTP::Request.new;
    HTTP::Request.new(method => HTTP::Request::RequestMethod, url => Any, file => Any, uri => Any, host
    => Str, port => Int, scheme => Str, header => HTTP::Header.new(fields => []), content => Any, protoc
    ol => "HTTP/1.1", binary => Bool::False, text-types => Array[Str].new())
    > $r.header.WHAT
    (Header)
    > $r.header.^methods
    (new field init-field push-field remove-field header-field-names hash clear Str parse fields)
    >

    可以看到, 这个 $r.header 就是一个HTTP::Header对象。(HTTP::Header对象设置HEADER信息后面有说)

    怎么设置Header信息呢?很简间, 下面是一个例子:

    $r.header.field(:user-Agent<this is a ie>);#设置头部信息

    把你要设置的header信息当成一个字典传入到$r.header.field()当参数就行

    我们还可以在创建对象时设置GET/POST与HEADER信息:

     

    multi method new(*%args)
    multi method new(Str $method, URI $uri, HTTP::Header $header);
    A constructor, the first form takes parameters like:
    =item method => URL, where method can be POST, GET ... etc.
    =item field => values, header fields
    my $req = HTTP::Request.new(:GET<example.com>, :h1<v1>);

     

     

     

     

    0x6使用这个HTTP::Request对象:

    如果我们把我们要设置的都设置完了, 准备发送请求, 可以这样发送:

    my $u = HTTP::UserAgent.new;
    my $result = $u.request($r);

     

    现在来说说 HTTP::Header。

    方法:

    new field init-field push-field remove-field header-field-names hash clear Str parse fields

     

    0x1 field设置:

    use HTTP::Header; 
    my $h = HTTP::Header.new;
    $h.field(Accept => 'text/plain');
    say $h.field('Accept');
    $h.remove-field('Accept');

    0x2 在new 时设置:

     my $head = HTTP::Header.new(:h1<v1>, :h2<v2>);

     

    0x3 push-header:

    文档里有这个方法, 但本人没测试成功。

    my $head = HTTP::Header.new;
    $head.push-header( HTTP::Header::Field.new(:name<n1>, :value<v1>) );
    say ~$head;

    也就是说, 用push-header导入一个HTTP::Header::Field对象, 这个对象设置header时可以用如下方法:

    use HTTP::Header::Field;
    my $header = HTTP::Header::Field.new(:name<Date>, values => (123, 456));

    注意这个 name, values 关键字是固定的。

    0x4清除设置的header:

    my $head = HTTP::Header.new(:h1<v1>, :h2<v2>);
    $head.clear;

     

    一般来说, 你知道HTTP::Header方法后, 当你创建一个HTTP::Request后, 就可以直接用  $request.header.field(:user-agent<firefox>) 这种型式设置即可。

     

    HTTP::UserAgent

    0x1 GET请求:

    my $u = HTTP::UserAgent.new;
    my $result = $u.get($url);

    0x2 POST请求:

    my $u = HTTP::UserAgent.new;
    my %data = :user<root>,:password<password>;
    my $result = $u.post($url, %data);

    0x3设置HEADER信息:

    我们可以不先创建request,再用request设置好header后,再导入request到HTTP::UserAgent中用$u.request($request)去请求。我们可以在GET/POST请求时设置好HEADER。

    下面是get的方法定义

    multi method get(Str $url is copy, :bin?, *%headers) returns  HTTP::Response
    multi method get(URI $uri, :bin?, *%headers) returns HTTP::Response

    下面是post方法定义

    multi method post(URI $uri, %form, *%header ) -> HTTP::Response
    multi method post(Str $uri, %form, *%header ) -> HTTP::Response

    可以看到, get/post请求时, 都有一个%header字典, 那我们就可以这样设置:

    > my $result =$a.get('http://localhost/1.php', :user-agent<ooooooooooooo>)
    > my $result =$a.post('http://localhost/1.php', (:a<1>),:user-agent<ooooooooooooo>)

    注意POST请求时第二个参数是必须要有的, 这个就是POST的数据, 而第三个参数是一个收集型的hash的设置, 是设置header用的, 收集型参数可以不传送数据。

     

    0x4设置COOKIE:

    我们看一下HTTP::UserAgent的对象:

    > $a
    HTTP::UserAgent.new(timeout => 180, useragent => Any, cookies => HTTP::Cookies.new(cookies => [], fi
    le => "C:\Users\ADMINI~1\AppData\Local\Temp\mKsrWNHtC8", autosave => 1), auth_login => Any, au
    th_password => Any, max-redirects => 5, redirects-in-a-row => 0, throw-exceptions => Bool, debug =>
    Any, debug-handle => IO::Handle, http-proxy => Any, no-proxy => [])
    >

    可以看到, 里面有一个 cookies => HTTP::Cookies, 我们看一下 HTTP::UserAgent的方法有哪些:

    > $a.^methods
    (BUILD auth get post request get-content get-chunked-content get-response get-connection is-cgi get-
    proxy no-proxy use-proxy setup-auth use-auth timeout useragent cookies auth_login auth_password max-
    redirects redirects-in-a-row throw-exceptions debug debug-handle http-proxy)
    >

    里面有一个cookies方法, 我们可以查看一下这个方法是什么:

    > $a.cookies;
    HTTP::Cookies.new(cookies => [], file => "C:\Users\ADMINI~1\AppData\Local\Temp\mKsrWNHtC8", au
    tosave => 1)
    > $a.cookies.WHAT;
    (Cookies)
    > $a.cookies.^methods;
    (extract-cookies add-cookie-header save load clear-expired clear set-cookie push-cookie Str cookies
    file autosave)
    >

    这个原来就是前面所说的HTTP::Cookies对象。

    所以设置cookies时, 我们可以这样设置:

     

    $a.cookies.set-cookie('Set-Cookie:a=1')

     

    0x5 request方法:

    HTTP::UserAgent里有一个request方法, 这个方法就是用来导入前面所说的HTTP::Request对象用的:

    my $r = HTTP::Request.new;
    #do something
    my $ua = HTTP::UserAgent.new;
    my $result = $ua.request($r);

     

     

     

    HTTP::Response响应对象

    > my $rp = HTTP::Response.new
    HTTP::Response.new(status-line => "200 OK", code => 200, request => HTTP::Request, header => HTTP::H
    eader.new(fields => []), content => Any, protocol => "HTTP/1.1", binary => Bool::False, text-types =
    > Array[Str].new())
    > $rp.^methods;
    (BUILD new content-length is-success has-content is-chunked set-code next-request Str status-line co
    de request add-content remove-field content-encoding push-field protocol text-types inflate-content
    decoded-content AUTOGEN parse header charset is-text Str content new clear content-type media-type i
    s-binary binary)
    >

     

    上面是它的对象方法

    0x1获取响应状态码:

    > $rp.status-line;
    200 OK
    >

     

    0x2获取返回内容:

    > $result.content
    <pre>array(0) {
    }
    array(0) {
    }
    ooooooooooooo
    > $result.Str
    HTTP/1.1 200 OK
    Date: Fri, 07 Jul 2017 15:51:43 GMT
    Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9
    X-Powered-By: PHP/5.3.29
    Connection: close
    Transfer-Encoding: chunked
    Content-Type: text/html
    
    <pre>array(0) {
    }
    array(0) {
    }
    ooooooooooooo
    
    >

    可以用content或Str

    有时可能也要用到decoded-content:

    > $result.decoded-content
    <pre>array(0) {
    }
    array(0) {
    }
    ooooooooooooo
    >

     

     

     >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 提示: get/post方法中, url不要有空格, 空格要用%20代替, 否则会报错。

    如果要查看设置好后的包数据, 可以像这样:

     


    这里的$html为response对像
    > $html.request.WHAT (Request) > $html.request.^methods (new set-method uri host port scheme add-cookies add-content add-form-data form-data make-boundary S tr parse method url file add-content remove-field content-encoding push-field protocol text-types in flate-content decoded-content AUTOGEN parse header charset is-text Str content new clear content-typ e media-type is-binary binary) > $html.request.host localhost > $html.request.Str POST /1.php HTTP/1.1 Host: localhost Content-Length: 11 Content-Type: application/x-www-form-urlencoded Connection: close 5=6&1=2&3=4 >
    当然 , 如果$r为request对像, 也可以像下面这样查。
    > $r.Str
    POST /1.php HTTP/1.1
    Host: localhost
    Content-Length: 11
    Content-Type: application/x-www-form-urlencoded
    Connection: close

    5=6&1=2&3=4


     

     

     

     

     

     

    参考链接:

    https://github.com/sergot/http-useragent

     

  • 相关阅读:
    创建部署规划
    并发容器Map之一:(jdk1.8) ConcurrentHashMap的红黑树实现分析
    CopyOnWrite容器之二:CopyOnWriteArraySet
    jQuery1.5的新特征subclass——jQuery插件机制的救赎
    getElementsByTagName
    facebook是如何管理代码的
    由addClass衍生出来的字符串去重问题
    节点排序
    Sizzle是怎样工作的
    我的模块加载系统 v3
  • 原文地址:https://www.cnblogs.com/perl6/p/7134600.html
Copyright © 2011-2022 走看看