最新消息:最新信息可以到系统基本设置里填写,如果不想要这一栏可以修改head.htm,将第53行到55行删除即可

Java 爬虫遇到需要登录的网站,该怎么办?

技巧资源 dedesos.com

这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫,就是这么的简单 中,我们简单的学习了一下如何利用 Java 进行网络爬虫。在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录的网站,我们该怎么办?

在做爬虫时,遇到需要登陆的问题也比较常见,比如写脚本抢票之类的,但凡需要个人信息的都需要登陆,对于这类问题主要有两种解决方式:一种方式是手动设置 cookie ,就是先在网站上面登录,复制登陆后的 cookies ,在爬虫程序中手动设置 HTTP 请求中的 Cookie 属性,这种方式适用于采集频次不高、采集周期短,因为 cookie 会失效,如果长期采集的话就需要频繁设置 cookie,这不是一种可行的办法,第二种方式就是使用程序模拟登陆,通过模拟登陆获取到 cookies,这种方式适用于长期采集该网站,因为每次采集都会先登陆,这样就不需要担心 cookie 过期的问题。

为了能让大家更好的理解这两种方式的运用,我以获取豆瓣个人主页昵称为例,分别用这两种方式来获取需要登陆后才能看到的信息。获取信息如下图所示:

手动设置 cookie 的方式,这种方式比较简单,我们只需要在豆瓣网上登陆,登陆成功后就可以获取到带有用户信息的cookie,豆瓣网登录链接:https://accounts.douban.com/passport/login。如下图所示:

/**
 * 手动设置 cookies
 * 先从网站上登录,然后查看 request headers 里面的 cookies
 * @param url
 * @throws IOException
public void setCookies throws IOException {
 Document document = Jsoup.connect
 // 手动设置cookies
 .header
 .get;
 if  {
 // 获取豆瓣昵称节点
 Element element = document.select.first;
 if  {
 System.out.println;
 return;
 // 取出豆瓣节点昵称
 String userName = element.ownText;
 System.out.println;
 } else {
 System.out.println;
复制代码

从代码中可以看出跟不需要登陆的网站没什么区别,只是多了一个.header,我们把浏览器中的 cookie 复制到这里即可,编写 main 方法

public static void main throws Exception {
 // 个人中心url
 String user_info_url = "https://www.douban.com/people/150968577/";
 new CrawleLogin.setCookies;
复制代码

运行 main 得到结果如下:

模拟登陆的方式可以解决手动设置 cookie 方式的不足之处,但同时也引入了比较复杂的问题,现在的验证码形形色色、五花八门,很多都富有挑战性,比如在一堆图片中操作某类图片,这个还是非常有难度,不是随便就能够编写出来。所以对于使用哪种方式这个就需要开发者自己去衡量利弊啦。今天我们用到的豆瓣网,在登陆的时候就没有验证码,对于这种没有验证码的还是比较简单的,关于模拟登陆方式最重要的就是找到真正的登陆请求、登陆需要的参数。 这个我们就只能取巧了,我们先在登陆界面输入错误的账号密码,这样页面将不会跳转,所以我们就能够轻而易举的找到登陆请求。我来演示一下豆瓣网登陆查找登陆链接,我们在登陆界面输入错误的用户名和密码,点击登陆后,在 network 查看发起的请求链接,如下图所示:

/**
 * Jsoup 模拟登录豆瓣 访问个人中心
 * 在豆瓣登录时先输入一个错误的账号密码,查看到登录所需要的参数
 * 先构造登录请求参数,成功后获取到cookies
 * 设置request cookies,再次请求
 * @param loginUrl 登录url
 * @param userInfoUrl 个人中心url
 * @throws IOException
public void jsoupLogin throws IOException {
 // 构造登陆参数
 Map String,String data = new HashMap ;
 data.put;
 data.put;
 data.put;
 data.put;
 data.put;
 Connection.Response login = Jsoup.connect
 .ignoreContentType // 忽略类型验证
 .followRedirects // 禁止重定向
 .postDataCharset
 .header
 .header
 .header
 .header
 .header AppleWebKit/537.36  Chrome/75.0.3770.100 Safari/537.36")
 .data
 .method
 .execute;
 login.charset;
 // login 中已经获取到登录成功之后的cookies
 // 构造访问个人中心的请求
 Document document = Jsoup.connect
 // 取出login对象里面的cookies
 .cookies)
 .get;
 if  {
 Element element = document.select.first;
 if  {
 System.out.println;
 return;
 String userName = element.ownText;
 System.out.println;
 } else {
 System.out.println;
复制代码

这段代码分两段,前一段是模拟登陆,后一段是解析豆瓣主页,在这段代码中发起了两次请求,第一次请求是模拟登陆获取到 cookie,第二次请求时携带第一次模拟登陆后获取的cookie,这样也可以访问需要登陆的页面,修改 main 方法

public static void main throws Exception {
 // 个人中心url
 String user_info_url = "https://www.douban.com/people/150968577/";
 // 登陆接口
 String login_url = "https://accounts.douban.com/j/mobile/login/basic";
 // new CrawleLogin.setCookies;
 new CrawleLogin.jsoupLogin;
复制代码

运行 main 方法,得到如下结果:

除了使用 jsoup 模拟登陆外,我们还可以使用 httpclient 模拟登陆,httpclient 模拟登陆没有 Jsoup 那么复杂,因为 httpclient 能够像浏览器一样保存 session 会话,这样登陆之后就保存下了 cookie ,在同一个 httpclient 内请求就会带上 cookie 啦。httpclient 模拟登陆代码如下:

/**
 * httpclient 的方式模拟登录豆瓣
 * httpclient 跟jsoup差不多,不同的地方在于 httpclient 有session的概念
 * 在同一个httpclient 内不需要设置cookies ,会默认缓存下来
 * @param loginUrl
 * @param userInfoUrl
public void httpClientLogin throws Exception{
 CloseableHttpClient httpclient = HttpClients.createDefault;
 HttpUriRequest login = RequestBuilder.post
 .setUri)// 登陆url
 .setHeader
 .setHeader
 .setHeader
 .setHeader
 .setHeader AppleWebKit/537.36  Chrome/75.0.3770.100 Safari/537.36")
 // 设置账号信息
 .addParameter
 .addParameter
 .addParameter
 .addParameter
 .addParameter
 .build;
 // 模拟登陆
 CloseableHttpResponse response = httpclient.execute;
 if .getStatusCode == 200){
 // 构造访问个人中心请求
 HttpGet httpGet = new HttpGet;
 CloseableHttpResponse user_response = httpclient.execute;
 HttpEntity entity = user_response.getEntity;
 String body = EntityUtils.toString;
 // 偷个懒,直接判断 缺心眼那叫单纯 是否存在字符串中
 System.out.println));
 }else {
 System.out.println;
复制代码

运行这段代码,返回的结果也是 true。

有关 Java 爬虫遇到登陆问题就聊得差不多啦,来总结一下:对于爬虫遇到登陆问题有两种解决办法,一种是手动设置cookie,这种方式适用于短暂性采集或者一次性采集,成本较低。另一种方式是模拟登陆的方式,这种方式适用于长期采集的网站,因为模拟登陆的代价还是蛮高的,特别是一些变态的验证码,好处就是能够让你一劳永逸

以上就是 Java 爬虫时遇到登陆问题相关知识分享,希望对你有所帮助,下一篇是关于爬虫是遇到数据异步加载的问题。如果你对爬虫感兴趣,不妨关注一波,相互学习,相互进步

源代码:源代码

文章不足之处,望大家多多指点,共同学习,共同进步

打个小广告,欢迎扫码关注微信公众号:「平头哥的技术博文」,一起进步吧。

    与本文相关的文章

    网友最新评论