Spring Boot + Java爬虫 + 部署到Linux (三、Java爬虫使用代理,模拟登录,保存cookie)

    很多网站对资源都有一定的限制。如果不登录,不是网站的登录用户(会员)访问的话,一些资源会访问不到。这对我们爬虫是十分不利的。而绝大多数网站都是通过登录之后,向浏览器设置cookie,达到验证的功能。

    由于目标网站很多有时候可能会被q,而无法一般的访问。所以我们要使用代理解决障碍。这里呢,我推荐ss,既好用又便宜。手机、电脑均有客户端可以使用。方法原理也比较简单,首先需要租一台便宜的国外服务器,然后远程连接上,安装ss的服务器,然后在我们的设备上装上客户端,就可以达到目的了。更详细的步骤,可以百度搜索,这里不详细说了。一般情况下,ss的代理的端口号是1080,或者根据自己的对应设置。如果不需要fq,则可跳过代理部分。

    当我们请求资源时,在请求的头部的Cookie这一项里一般会包含我们的账号、密码(加密处理后的)等信息。只有带有正确Cookie的请求,才能访问到有权限的资源。至于如何获取Cookie,有一种很简单的方式,就是直接通过浏览器登录帐号。然后当你再访问这个网站的时候(在cookie有效期内),使用浏览器的开发者工具(审查元素、检查),然后选中network(网络)这一项,会发现很多的请求和响应,如果没有看到,就刷新一下页面。在主要的访问的请求、响应上,点击打开,就会看到请求头和响应头(Request Headers、Response Headers)。在请求头上,就可以看到Cookie了。把这个Cookie复制下来,放到上节中的爬虫的请求的头部的Cookie中,就可以实现访问需要权限的资源了。

    登录百度和使用Chrome查看:

Spring Boot + Java爬虫 + 部署到Linux (三、Java爬虫使用代理,模拟登录,保存cookie)_第1张图片



这种是手动的方法,下面开始使用Java爬虫的方式实现登录和保存Cookie。

    首先,我们要找到登录的URL(不是登录页面的,而是点击“登录”按钮,所访问的URL),然后找一下,需要几项内容(用户名、密码、等)需要放在Post请求里。最后就是发送请求,接收响应,然后拿到响应头里面的Set-Cookie里的Cookie信息。以Chrome为例。

    第一步:找到登录的URL

    我们要转到目标网站的登录页面,如果已经登录了,则先注销(log out)。在登录页面的“登录”按钮处右键检查,可以看到登录被包含在一个表单(form)中,找到form的action属性,action属性的值就是表单提交也就是登录的URL。如果没有action属性,我就不会了。只能通过上面手动的方法设置Cookie了。

    

 第二步:找到输入的标签的name属性

    把鼠标放到输入框上,右键检查,可以看到的标签,记录下name的名字。有时候,很多登录会有选项设置是否保存Cookie,一般叫“记住我吗?”、“xxx天免登录”等。用同样的方法查看一下,一般会有个默认值,比如“1”等,表示保存,都记录下来。

    Spring Boot + Java爬虫 + 部署到Linux (三、Java爬虫使用代理,模拟登录,保存cookie)_第2张图片

第三步:Java使用代理,模拟登录,设置cookie

    继续使用我们的httpclient包(见第二节)。这次,我们要使用Http的Post请求,还要设置代理和保存Cookie。设置代理,使用RoutePlanner。保存Cookie使用CookieStore。post的参数列表为List类型,然后添加到请求中。

    下面的代码是一个例子。有时候Cookie可能有很多,但是我们需要的可能只有用户名和密码对应的cookie就可以了。例子网站呢,有两个重要的cookie,name分别为ipb_member_id和ip_pass_hash。从名字中可以看出是用户的id和密码的哈希值。我们需要这两个cookie,另外呢,可能会出现登录失败的情况(用户名、密码不匹配),所以我们还要验证是否登录成功了。登录成功可以根据返回的页面里面的内容来判断。最后将这些结果返回出去。

    


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.message.BasicNameValuePair;

public class Login {

	private static final String LOGIN_URL = "your login url";
	private static final String USER = "UserName";
	private static final String PASS = "PassWord";
	private static final String COOKIE = "CookieDate";
	private static final boolean PROXY = true;	//默认使用代理
	private static final String CODING = "utf8";	//默认编码utf8
	private static final String PROXY_HOST = "127.0.0.1";
	private static final int PROXY_PORT = 8118;//一般是1080,或者其他自己设置的端口
	private static final int CONNECT_TIMEOUT = 10000;
	private static final String SUCCESS_FLAG = "Thanks";//成功的标志
	private static final String MEMBER = "ipb_member_id";
	private static final String COOKIE_PASS = "ipb_pass_hash";
	public static String[] eLogin(String username, String password){
		String[] ret = new String[3]; //初始为null,返回数组存储着成功与否以及cookie信息
		HttpClientBuilder httpClientBuilder = HttpClients.custom();
		//设置代理
		if(PROXY){
			HttpHost proxy = new HttpHost(PROXY_HOST, PROXY_PORT);
			DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
			httpClientBuilder.setRoutePlanner(routePlanner);
		}
		//设置Cookie
		CookieStore cookieStore = new BasicCookieStore();
		httpClientBuilder.setDefaultCookieStore(cookieStore);
		//设置超时
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).build();
		CloseableHttpClient httpClient = httpClientBuilder.build();
		HttpPost httpPost = new HttpPost(LOGIN_URL);
		httpPost.setConfig(requestConfig);
		//设置参数列表
		List para = new ArrayList<>();
		para.add(new BasicNameValuePair(USER, username));
		para.add(new BasicNameValuePair(PASS, password));
		para.add(new BasicNameValuePair(COOKIE, "1")); //默认一直是1,表示保存
		//设置参数
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(para));
		} catch (UnsupportedEncodingException e) {
			System.out.println("登录设参数失败!");
			e.printStackTrace();
		}
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			String html = stream2String(entity.getContent());
			List cookies= cookieStore.getCookies();  //响应成功时,cookieStore里面已经存好cookies了
			//设置返回结果
			if(html.contains(SUCCESS_FLAG)){
				ret[0] = "true";
				ret[1] = getValueByName(cookies, MEMBER);
				ret[2] = getValueByName(cookies, COOKIE_PASS);
				return ret;
			}
		} catch (ClientProtocolException e) {
			System.out.println("连接超时!");
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			CloseUtil.close(response);
			CloseUtil.close(httpClient);
		}
		ret[0] = "false";
		return ret;
	}
        //输入流转字符串
	private static String stream2String(InputStream in){
		
		BufferedReader br = null;
		StringBuffer sb = new StringBuffer();
		try {
			
			br = new BufferedReader(new InputStreamReader(in, CODING));
			String line = null;
			while(null!=(line = br.readLine())){
				sb.append(line+"\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			CloseUtil.close(in);
			CloseUtil.close(br);
		}
		return sb.toString();
	}
        //根据cookie的名字,从所有的cookie中找到值。
	private static String getValueByName(List cookies, String name){
		String value = null;
		for(Cookie c:cookies){
			if(name.equals(c.getName())){
				value = c.getValue();
				break;
			}
		}
		return value;
	}
}
 
  

    根据不同的网站进行不同的参数调整,最终成功的获得我们所需要的一些cookie,将这些cookie运用到第二节的Java爬虫中,就能实现对有权限的资源的爬取了。另外这节中的设置代理的方法,也可运用到爬虫中,同样的设置就行了。

    其实,如果只是自己爬虫的话,可以直接采用刚开始说的手动找cookie的方法,找到自己的cookie。然后将其固定在爬虫程序的请求中就行了

你可能感兴趣的:(Spring,Boot,爬虫)