如何模拟浏览器进行网络请求?

  1. HTTP协议

  2. Java网络请求原生API

    • 2.1 Java网络请求原生API-Get请求

    • 2.2 Java网络请求原生API-Post请求

  3. 使用HttpClient进行网络请求

    • 3.1 使用HttpClient进行Get请求

    • 3.2 使用HttpClient进行POST请求

    • 3.3 使用HttpClient进行Get请求-简单

    • 3.4 使用HttpClient进行POST请求-简单

1丶HTTP协议

HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。

HTTP.jpg

客户端向服务器发送一个请求,请求头包含请求的方法、URL、协议版本、以及包含请求修饰符、客户信息和内容的类似于MIME的消息结构。

服务器以一个状态行作为响应,响应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。

通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个指示头域结束的空行和可选的消息体组成。

RequestHeader.jpg

HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

HTTP常见状态码 所有的状态码:百度百科
http_code.png

2丶Java网络请求原生API

HttpUrlConnection

Get 方式请求网络基本流程

  • 给定一个域名:http://www.wangshuangli.top

  • 创建URL

  • 通过URL对象打开一个连接

  • 判断请求状态是否等于200

    • 输入流:获取服务端的响应数据

    • 使用BufferReader读取数据

    • 关闭流

Post 方式请求网络基本流程

  • 给定一个域名:http://www.wangshuangli.top

  • 创建URL

  • 通过URL对象打开一个连接

  • 设定Post请求方式

    • 指定 requestMethod为post

    • 打开 conn.setDoOutput(true)

  • 提交数据到服务器

    • 获取outputStream

    • 写出数据

    • flush and close

  • 判断请求状态是否等于200

    • 输入流:获取服务端的响应数据

    • 使用BufferReader读取数据

    • 关闭流

2.1丶Java网络请求原生API-Get请求

使用 JDK 原生 API 发送Get请求

public class Get {
    public static final String USER_AGENT = "Mozilla/5.0";
    public static void main(String[] args) throws IOException {
        //1、准备要访问的URL
        String url = "http://www.wangshuangli.top";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //2、设置Http协议的参数
        // optional default is GET
        con.setRequestMethod("GET");
        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);

        //3、发起HTTP请求,获取状态码
        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'GET' request to URL : " + url);
        System.out.println("Response Code : " + responseCode);

        //4、如果是正常相应,读取数据(二进制数据)
        if (responseCode == 200) {
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            //5.将二进制数据转化成字符串
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            //6.关闭资源
            in.close();
            //print result
            System.out.println(response.toString());
        }
    }
}

2.2丶Java网络请求原生API-Post请求

使用原生API发送Post请求

public class Post {
    public static final String USER_AGENT = "Mozilla/5.0";
    public static void main(String[] args) throws IOException {
        //1.准备要访问的URL
        String url = "http://www.wangshaungli.top/login/login.html";
        URL obj = new URL(url);
        //2.发起一个网络请求
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //添加请求头信息
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", Post.USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        String urlParameters = "username=maoxiangyi&password=&maoxiangyi&reURL=http://shop.itcast.cn/item/itemList.html";

        //3.发送POST请求,获取状态码
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);
        //4.判断状态码是否是200
        if (responseCode == 200) {
            //5.得到服务端返回的二进制数据
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            //5.将二进制数据转化成字符串
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            //6.关闭资源
            in.close();
            System.out.println(response.toString());
        }
    }
}

3丶使用HttpClient进行网络请求

使用HttpClient进行网络请求

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

HttpClient官方文档

HttpClient存在的意义

  • 超文本传输协议(HTTP)可能是当今互联网上使用的最重要的协议

  • 虽然java.net包提供了通过HTTP访问资源的基本功能,但它并没有提供许多应用程序所需的完全灵活性或功能

使用HttpClient的maven依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.5.2</version>
</dependency>

3.1丶使用HttpClient进行Get请求

  • HttpClients.createDefault 创建一个客户端

  • HttpGet 创建一个Get请求

  • httpclient.execute(httpGet) 执行一个请求

  • CloseableHttpResponse 获取返回值

    • getStatusLine 获取状态信息

    • EntityUtils 操作返回内容

代码实现

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.Charset;


public class SimpleGet {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://www.wangshaungli.top");
        CloseableHttpResponse response = httpclient.execute(httpGet);
        System.out.println(response.getStatusLine());
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            String html = EntityUtils.toString(entity, Charset.forName("utf-8"));
            System.out.println(html);
        }
        response.close();
    }
}

3.2丶使用HttpClient进行Post请求

使用HttpClient进行Post请求

  • HttpClients.createDefault 创建一个客户端

  • HttpPost 创建一个Post请求

    • UrlEncodedFormEntity 封装表单信息

  • httpclient.execute(HttpPost) 执行一个请求

  • CloseableHttpResponse 获取返回值

    • getStatusLine 获取状态信息

    • EntityUtils 操作返回内容

代码实现

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


public class SimplePost {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("http://www.wangshaungli.top/login/login.html");
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("username", "wangshuangli"));
        nvps.add(new BasicNameValuePair("password", "wangshaungli"));
        nvps.add(new BasicNameValuePair("reURL", "http://shop.itcast.cn/item/itemList.html"));
        httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        CloseableHttpResponse response = httpclient.execute(httpPost);
        System.out.println(response.getStatusLine());
        //如果登录之后需要重定向,获取重定向的值
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            System.out.println(header);
        }
        if (response.getStatusLine().getStatusCode() == 302) {
            Header[] locations = response.getHeaders("Location");
            String url = locations[0].getValue();
            System.out.println(url);
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response1 = httpclient.execute(httpGet);
            if (response1.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response1.getEntity();
                String html = EntityUtils.toString(entity, Charset.forName("utf-8"));
                System.out.println(html);
            }
            response1.close();
        }
        response.close();
    }
}

3.3丶使用HttpClient进行Get请求-简单方式

使用HttpClient进行Get请求-简单方式

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;

import java.io.IOException;
import java.nio.charset.Charset;


public class EasyGet {
    public static void main(String[] args) throws IOException {
        String html = Request.Get("http://www.wangshuangli.top").execute().returnContent().asString(Charset.forName("UTF-8"));
        System.out.println(html);
    }
}

3.4丶使用HttpClient进行Post请求-简单

使用HttpClient进行Post请求-简单方式

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;


public class EasyPost {
    public static void main(String[] args) throws IOException {
        HttpResponse response = Request.Post("http://shop.itcast.cn/login/login.html")
                .bodyForm(Form.form().add("username", "wangshaungli").add("password", "wangshaungli").add("reURL","http://www.wangshaungli.top/item/itemList.html").build())
                .execute().returnResponse();
        if (response.getStatusLine().getStatusCode() == 302) {
            Header[] locations = response.getHeaders("Location");
            String url = locations[0].getValue();
            System.out.println(url);
            HttpGet httpGet = new HttpGet(url);
            String html =  Request.Get(url).execute().returnContent().asString(Charset.forName("UTF-8"));
            System.out.println(html);
        }
    }
}

标签: none

相关文章推荐

添加新评论,含*的栏目为必填