[Jsoup] 使用Jsoup发送Request Payload(请求负载)

本文地址:https://blog.csdn.net/dietime1943/article/details/87312903
本文作者:bluetata  [email protected]
****** 如果你看到这一行,说明网络爬虫可能在本人还没有发布完成的时候就抓走了我的文章,导致内容不完整,请去上述的原文链接查看原文 ******

本文章意在讲解如何使用Post请求Request payload类型的form提交,以及如何使用Jsoup进行上传文件。

本文大纲如下:

  1. 关于Request Payload(请求负载) 的解释说明
  2. 使用Jsoup提交Json类型的Request Payload(请求负载)
  3. 使用Jsoup提交multipart/form-data类型的Request Payload(请求负载) / 使用Jsoup上传文件

1. 关于 Request Payload(请求负载) 的解释说明

Request Payload(请求负载):payload body of a HTTP Request 通常在传输数据时,为了使数据传输更可靠,要把原始数据分批传输,并且在每一批数据的头和尾都加上一定的辅助信息,比如这一批数据量的大小,校验位等,这样就相当于给已经分批原始数据加一些外套,这些外套起到标示作用,使得原始数据不易丢失。一批数据加上它的“外套”,就形成了传输通道中基本的传输单元(数据帧或者数据包)。消息体就是“外套”,即标记着原始数据的大小等的辅助信息传输单元中的原始数据就是有效负载数据

通常在发送POSTPUTPATCH请求的时候才可以携带Payload数据

如果一个请求为:Content-Type: application/json 类型,它的请求格式类似于:

POST /some-path HTTP/1.1
Content-Type: application/json

{ "username" : "sekito", "password" : "password123" }

另一种,如果一个请求方式为POST,请求类型为 Content-Type: application/x-www-form-urlencoded 或者 Content-Type: multipart/form-data,请求格式类似于:

POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=sekito&password=password123

而在复合数据类型(multipart/form-data)提交的时候,你在F12开发者工具看到的类似于如下格式:

------WebKitFormBoundaryO5quBRiT4G7Vm3R7
Content-Disposition: form-data; name="message"

Hello World
------WebKitFormBoundaryO5quBRiT4G7Vm3R7
Content-Disposition: form-data; name="file"; filename="Test.txt"
Content-Type: text/plain

aaaTest
------WebKitFormBoundaryO5quBRiT4G7Vm3R7--

针对multipart/form-data类型提交请求的时候,F12看到的格式解释如下:

第一段数据的Key为 name="message" 中的 "message",value为 "Hello World"
第二段数据的Key为 name="file" 中的 "file",file名为 "Test.txt",文件中的内容为:"aaaTest"。

解释完Payload相关,下面会分别从json形式 和 multipart/form-data 形式的request payload 做模拟请求

2. 使用Jsoup提交Json类型的Request Payload(请求负载)

比较常见的一种Json形式Request Payload提交请求的例子就是在分页的时候,post提交分页请求,一般为json传递:

该网站即为比较典型的动态分页,且提交数据为Request Payload的形式,这种Json格式的提交,早在[Jsoup] 如何发送Json请求(how to send json by Jsoup) 一文中详细介绍过,这里只针对该情况写出模拟示例(本示例使用的阿里的fastjson):

        JSONObject payload = new JSONObject();
        // {"pageIndex":2,"pageSize":20,"typeTab":1}
        payload.put("pageIndex", 2);
        payload.put("pageSize", 20);
        payload.put("typeTab", 1);
        
        // String jsonBody = "{\"name\":\"ACTIVATE\",\"value\":\"E0010\"}";
        
        Connection connection = Jsoup.connect("https://www.tablenow.vn/ho-chi-minh/bo-suu-tap")
                .userAgent("Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36") // User-Agent of Chrome 55
                .referrer("https://www.tablenow.vn/ho-chi-minh/bo-suu-tap")
                .header("Content-Type", "application/json;charset=UTF-8")
                .header("Accept", "application/json, text/plain, */*")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("Accept-Language", "zh-CN,zh;q=0.9,ja;q=0.8,en;q=0.7")
                .header("Connection", "keep-alive")
                .requestBody(payload.toJSONString())
                .maxBodySize(100)
                .timeout(1000 * 10)
                .method(Connection.Method.POST);
 
        Response response = connection.execute();

3. 使用Jsoup提交multipart/form-data类型的Request Payload(请求负载) / 使用Jsoup上传文件

在下图Request headers中可以看到,Content-Type为:multipart/form-data; boundary=--------------------2043647828081

 

这里的 "boundary=--------------------2043647828081" 的主要作用是分隔作用,用于指定数据的封装边界。关于boundary参数更多解释可以参照stack overflow中What is the boundary parameter in an HTTP multi-part (POST) Request?中指向的W3C解释链接。

对于带有boundary分隔数据的Request payload请求提交,Jsoup现在一般有3种思路:一种将F12开发者工具中看到的request payload看做是一个字符串,之后根据自己想要动态赋值value,来动态拼接一个和F12看到一模一样的字符串,之后将该字符串传递到requestBody中,另一种是将该字符串拆解成一个json对象,之后类似于上文提到过的按照json形式来提交。注意:以上该两种方式均为非upload数据流的request payload请求负载。

此文重点讲述第三种带有文件上传的方式,如果想查看上述两种的,请查看GitHub上提交的源码。

对于第三种Jsoup进行multipart/form-data的请求,在Jsoup 1.8.2 (Apr 13, 2015)前是不支持的,在 Jsoup 1.8.2 的时候提供了一个上传文件的API:data(String, String, InputStream),如果非要使用Jsoup 1.8.2之前的jar,那么可以考虑利用HttpClient进行模拟提交。

下图举例来说明:

在页面中可以看到第一个数据部分为一个input,其中name为:"text",其value为:"Jsoup upload",第二个数据部分为,一个上传选择框,其name为:"file1",上传的文件名为:"uploadTest.txt",文件里的内容为:"dump text"。

请求示例代码为:

        // upload file by jsoup
        File file1 = new File("C:/dir/file1.txt");
        FileInputStream fs1 = new FileInputStream(file1);

        Response response1 = Jsoup.connect("http://bluetata.com/")
            .data("text","Jsoup upload")            // 绑定数据
            .data("file1", "uploadTest.txt", fs1)   // 上传文件
            .method(Method.POST)
            .execute();

reflink:

[Jsoup] 如何发送Json请求(how to send json by Jsoup)
What's the difference between “Request Payload” vs “Form Data” as seen in Chrome dev tools Network tab
https://javarush.ru/groups/posts/1429-jsoup--multipartform-data-response
https://www.yoheim.net/blog.php?q=20120611
https://www.yoheim.net/blog.php?q=20171201

Jsoup学习讨论QQ群:50695115
Jsoup爬虫代码示例及博客内源码下载:https://github.com/bluetata/crawler-jsoup-maven
更多Jsoup相关文章,请查阅专栏:【Jsoup in action】

本文原创由`bluetata`发布于blog.csdn.net、转载请务必注明出处。

Flag Counter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章