Java 爬虫服务器被屏蔽的解决方案

这是 Java 爬虫系列博文的第四篇,在上一篇Java 爬虫数据异步加载如何解决,试试这两种办法! 中,我们从内置浏览器内核和反向解析法两个角度简单的聊了聊关于处理数据异步加载问题。在这篇文章中,我们简单的来聊一聊爬虫时,资源网站根据用户访问行为屏蔽掉爬虫程序及其对应的解决办法。

屏蔽爬虫程序是资源网站的一种保护措施,最常用的反爬虫策略应该是基于用户的访问行为。比如限制每台服务器在一定的时间内只能访问 X 次,超过该次数就认为这是爬虫程序进行的访问,基于用户访问行为判断是否是爬虫程序也不止是根据访问次数,还会根据每次请求的User Agent 请求头、每次访问的间隔时间等。总的来说是由多个因数决定的,其中以访问次数为主。

反爬虫是每个资源网站自保的措施,旨在保护资源不被爬虫程序占用。例如我们前面使用到的豆瓣网,它会根据用户访问行为来屏蔽掉爬虫程序,每个 IP 在每分钟访问次数达到一定次数后,后面一段时间内的请求返回直接返回 403 错误,以为着你没有权限访问该页面。所以我们今天再次拿豆瓣网为例,我们用程序模拟出这个现象,下面是我编写的一个采集豆瓣电影的程序

/**
 * 采集豆瓣电影
 */
public class CrawlerMovie {

  public static void main(String[] args) {
    try {
      CrawlerMovie crawlerMovie = new CrawlerMovie();
      // 豆瓣电影链接
      List<String> movies = crawlerMovie.movieList();
      //创建10个线程的线程池
      ExecutorService exec = Executors.newFixedThreadPool(10);
      for (String url : movies) {
        //执行线程
        exec.execute(new CrawlMovieThread(url));
      }
      //线程关闭
      exec.shutdown();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 豆瓣电影列表链接
   * 采用反向解析法
   *
   * @return
   */
  public List<String> movieList() throws Exception {
    // 获取100条电影链接
    String url = "https://movie.douban.com/j/search_subjects?type=movie&tag=热门&sort=recommend&page_limit=200&page_start=0";
    CloseableHttpClient client = HttpClients.createDefault();
    List<String> movies = new ArrayList<>(100);
    try {
      HttpGet httpGet = new HttpGet(url);
      CloseableHttpResponse response = client.execute(httpGet);
      System.out.println("获取豆瓣电影列表,返回验证码:" + response.getStatusLine().getStatusCode());
      if (response.getStatusLine().getStatusCode() == 200) {
        HttpEntity entity = response.getEntity();
        String body = EntityUtils.toString(entity, "utf-8");
        // 将请求结果格式化成json
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray data = jsonObject.getJSONArray("subjects");
        for (int i = 0; i < data.size(); i++) {
          JSONObject movie = data.getJSONObject(i);
          movies.add(movie.getString("url"));
        }
      }
      response.close();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      client.close();
    }
    return movies;
  }
}
/**
 * 采集豆瓣电影线程
 */
class CrawlMovieThread extends Thread {
  // 待采集链接
  String url;

  public CrawlMovieThread(String url) {
    this.url = url;
  }
  public void run() {
    try {
      Connection connection = Jsoup.connect(url)
          .method(Connection.Method.GET)
          .timeout(50000);
      Connection.Response Response = connection.execute();
      System.out.println("采集豆瓣电影,返回状态码:" + Response.statusCode());
    } catch (Exception e) {
      System.out.println("采集豆瓣电影,采集出异常:" + e.getMessage());
    }
  }
}

这段程序的逻辑比较简单,先采集到豆瓣热门电影,这里使用直接访问 Ajax 获取豆瓣热门电影的链接,然后解析出电影的详情页链接,多线程访问详情页链接,因为只有在多线程的情况下才能达到豆瓣的访问要求。豆瓣热门电影页面如下:

多次运行上面的程序,你最后会得到下图的结果

从上图中我们可以看出,httpclient 访问返回的状态码为 403 ,说明我们已经没有权限访问该页面了,也就是说豆瓣网已经认为我们是爬虫程序啦,拒接掉了我们的访问请求。我们来分析一下我们现在的访问架构,因为我们是直接访问豆瓣网的,所以此时的访问架构如下图所示:

我们想要突破这层限制的话,我们就不能直接访问豆瓣网的服务器,我们需要拉入第三方,让别人代替我们去访问,我们每次访问都找不同的人,这样就不会被限制了,这个也就是所谓的 IP代理。 此时的访问架构就变成了下面这张图:

我们使用的 IP代理,我们就需要有 IP代理池,接下来我们就来聊一聊 IP 代理池

IP 代理池

代理服务器有很多厂商在做这一块,具体的我就不说了,自己百度 IP 代理可以搜出一大堆,这些 IP代理商都有提供收费和免费的代理 IP,收费的代理 IP可用性高,速度快,在线上环境如果需要使用代理的话,建议使用收费的代理 IP。如果只是自己研究的话,我们就可以去采集这些厂商的免费公开代理 IP,这些 IP 的性能和可用性都比较差,但是不影响我们使用。

因为我们是 Demo 项目,所以我们就自己搭建 IP代理池。我们该怎么设计一个 IP代理池呢?下图是我画的简单 IP代理池架构图

从上面的架构图中,可以看出一个 IP 代理系统会涉及到 4 个模块,分别为 IP 采集模块、 IP 存储模块、IP 检测模块和 API 接口模块。

IP 采集模块

负责从各大 IP代理厂商采集代理 IP,采集的网站越多,代理 IP 的可用性就越高

IP 存储模块

存储采集回来的代理 IP,比较常用的是 Redis 这样的高性能的数据库,在存储方面我们需要存储两种数据,一种是检测可用的代理 IP,另一种是采集回来还未检测的代理 IP。

IP 检测模块

检测采集回来的 IP 是否可用,这样能够让我们提供的 IP 可用性变高,我们先过滤掉不可用的 IP。

API 接口模块

以接口的形式对外提供可用代理 IP

上面就是关于 IP代理池的相关设计,对于这些我们只需要简单了解一下就行了,因为现在基本上不需要我们去编写 IP代理池服务啦,在 GitHub 上已经有大量优秀的开源项目,没必要重复造轮子啦。我为大家选取了在 GitHub 上有 8K star 的开源 IP代理池项目 proxy_pool ,我们将使用它作为我们 IP 代理池。关于 proxy_pool 请访问:https://github.com/jhao104/proxy_pool

部署 proxy_pool

proxy_pool 是用 python 语言写的,不过这也没什么关系,因为现在都可以容器化部署,使用容器化部署可以屏蔽掉一些环境的安装,只需要运行镜像就可以运行服务了,并不需要知道它里面的具体实现,所以这个项目不懂 Python 的 Java 程序员也是可以使用的。proxy_pool 使用的是 Redis 来存储采集的 IP,所以在启动 proxy_pool 前,你需要先启动 Redis 服务。下面是 proxy_pool docker启动步骤。

拉取镜像

docker pull jhao104/proxy_pool

运行镜像

docker run --env db_type=REDIS --env db_host=127.0.0.1 --env db_port=6379 --env db_password=pwd_str -p 5010:5010 jhao104/proxy_pool

运行镜像后,我们等待一段时间,因为第一次启动采集数据和处理数据需要一段时间。等待之后访问 http://{your_host}:5010/get_all/,如果你得到下图所示的结果,说明 proxy_pool 项目你已经部署成功。

使用 IP 代理

搭建好 IP代理池之后,我们就可以使用代理 IP 来采集豆瓣电影啦,我们已经知道了除了 IP 之外,User Agent 请求头也会是豆瓣网判断访问是否是爬虫程序的一个因素,所以我们也对 User Agent 请求头进行伪造,我们每次访问使用不同的 User Agent 请求头。

我们为豆瓣电影采集程序引入 IP代理和 随机 User Agent 请求头,具体代码如下:

public class CrawlerMovieProxy {

  /**
   * 常用 user agent 列表
   */
  static List<String> USER_AGENT = new ArrayList<String>(10) {
    {
      add("Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19");
      add("Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
      add("Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1");
      add("Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");
      add("Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0");
      add("Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36");
      add("Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19");
      add("Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3");
      add("Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3");
    }
  };

  /**
   * 随机获取 user agent
   *
   * @return
   */
  public String randomUserAgent() {
    Random random = new Random();
    int num = random.nextInt(USER_AGENT.size());
    return USER_AGENT.get(num);
  }

  /**
   * 设置代理ip池
   *
   * @param queue 队列
   * @throws IOException
   */
  public void proxyIpPool(LinkedBlockingQueue<String> queue) throws IOException {

    // 每次能随机获取一个代理ip
    String proxyUrl = "http://192.168.99.100:5010/get_all/";

    CloseableHttpClient httpclient = HttpClients.createDefault();

    HttpGet httpGet = new HttpGet(proxyUrl);
    CloseableHttpResponse response = httpclient.execute(httpGet);
    if (response.getStatusLine().getStatusCode() == 200) {
      HttpEntity entity = response.getEntity();
      String body = EntityUtils.toString(entity, "utf-8");

      JSONArray jsonArray = JSON.parseArray(body);
      int size = Math.min(100, jsonArray.size());
      for (int i = 0; i < size; i++) {
        // 将请求结果格式化成json
        JSONObject data = jsonArray.getJSONObject(i);
        String proxy = data.getString("proxy");
        queue.add(proxy);
      }
    }
    response.close();
    httpclient.close();
    return;
  }

  /**
   * 随机获取一个代理ip
   *
   * @return
   * @throws IOException
   */
  public String randomProxyIp() throws IOException {

    // 每次能随机获取一个代理ip
    String proxyUrl = "http://192.168.99.100:5010/get/";

    String proxy = "";

    CloseableHttpClient httpclient = HttpClients.createDefault();

    HttpGet httpGet = new HttpGet(proxyUrl);
    CloseableHttpResponse response = httpclient.execute(httpGet);
    if (response.getStatusLine().getStatusCode() == 200) {
      HttpEntity entity = response.getEntity();
      String body = EntityUtils.toString(entity, "utf-8");
      // 将请求结果格式化成json
      JSONObject data = JSON.parseObject(body);
      proxy = data.getString("proxy");
    }
    return proxy;
  }

  /**
   * 豆瓣电影链接列表
   *
   * @return
   */
  public List<String> movieList(LinkedBlockingQueue<String> queue) {
    // 获取60条电影链接
    String url = "https://movie.douban.com/j/search_subjects?type=movie&tag=热门&sort=recommend&page_limit=40&page_start=0";
    List<String> movies = new ArrayList<>(40);
    try {
      CloseableHttpClient client = HttpClients.createDefault();
      HttpGet httpGet = new HttpGet(url);
      // 设置 ip 代理
      HttpHost proxy = null;
      // 随机获取一个代理IP
      String proxy_ip = randomProxyIp();
      if (StringUtils.isNotBlank(proxy_ip)) {
        String[] proxyList = proxy_ip.split(":");
        System.out.println(proxyList[0]);
        proxy = new HttpHost(proxyList[0], Integer.parseInt(proxyList[1]));
      }
      // 随机获取一个请求头
      httpGet.setHeader("User-Agent", randomUserAgent());
      RequestConfig requestConfig = RequestConfig.custom()
          .setProxy(proxy)
          .setConnectTimeout(10000)
          .setSocketTimeout(10000)
          .setConnectionRequestTimeout(3000)
          .build();
      httpGet.setConfig(requestConfig);
      CloseableHttpResponse response = client.execute(httpGet);
      System.out.println("获取豆瓣电影列表,返回验证码:" + response.getStatusLine().getStatusCode());
      if (response.getStatusLine().getStatusCode() == 200) {
        HttpEntity entity = response.getEntity();
        String body = EntityUtils.toString(entity, "utf-8");
        // 将请求结果格式化成json
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray data = jsonObject.getJSONArray("subjects");
        for (int i = 0; i < data.size(); i++) {
          JSONObject movie = data.getJSONObject(i);
          movies.add(movie.getString("url"));
        }
      }
      response.close();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {

    }
    return movies;
  }

  public static void main(String[] args) {
    // 存放代理ip的队列
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue(100);

    try {
      CrawlerMovieProxy crawlerProxy = new CrawlerMovieProxy();
      // 初始化ip代理队列
      crawlerProxy.proxyIpPool(queue);
      // 获取豆瓣电影列表
      List<String> movies = crawlerProxy.movieList(queue);

      //创建固定大小的线程池
      ExecutorService exec = Executors.newFixedThreadPool(5);
      for (String url : movies) {
        //执行线程
        exec.execute(new CrawlMovieProxyThread(url, queue, crawlerProxy));
      }
      //线程关闭
      exec.shutdown();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

}

/**
 * 采集豆瓣电影线程
 */
class CrawlMovieProxyThread extends Thread {
  // 待采集链接
  String url;
  // 代理ip队列
  LinkedBlockingQueue<String> queue;
  // 代理类
  CrawlerMovieProxy crawlerProxy;

  public CrawlMovieProxyThread(String url, LinkedBlockingQueue<String> queue, CrawlerMovieProxy crawlerProxy) {
    this.url = url;
    this.queue = queue;
    this.crawlerProxy = crawlerProxy;
  }

  public void run() {
    String proxy;
    String[] proxys = new String[2];
    try {
      Connection connection = Jsoup.connect(url)
          .method(Connection.Method.GET)
          .timeout(50000);

      // 如果代理ip队列为空,则重新获取ip代理
      if (queue.size() == 0) crawlerProxy.proxyIpPool(queue);
      // 从队列中获取代理ip
      proxy = queue.poll();
      // 解析代理ip
      proxys = proxy.split(":");
      // 设置代理ip
      connection.proxy(proxys[0], Integer.parseInt(proxys[1]));
      // 设置 user agent
      connection.header("User-Agent", crawlerProxy.randomUserAgent());
      Connection.Response Response = connection.execute();
      System.out.println("采集豆瓣电影,返回状态码:" + Response.statusCode() + " ,请求ip:" + proxys[0]);
    } catch (Exception e) {
      System.out.println("采集豆瓣电影,采集出异常:" + e.getMessage() + " ,请求ip:" + proxys[0]);
    }
  }
}

运行修改后的采集程序,可能需要多次运行,因为你的代理 IP 不一定每次都有效。代理 IP 有效的话,你将得到如下结果

结果中我们可以看出,40 次的电影详情页访问,有大量的代理 IP 是无效的,只有一小部分的代理 IP 有效。结果直接证明了免费的代理 IP 可用性不高,所以如果线上需要使用代理 IP 的话,最好使用收费的代理 IP。尽管我们自己搭建的 IP代理池可用性不是太高,但是我们设置的 IP 代理访问豆瓣电影已经成功了,使用 IP 代理成功绕过了豆瓣网的限制。

关于爬虫服务器被屏蔽,原因有很多,我们这篇文章主要介绍的是通过 设置 IP 代理和伪造 User Agent 请求头来绕过豆瓣网的访问限制。如何让我们的程序不被资源网站视为爬虫程序呢?需要做好以下三点:

  • 伪造 User Agent 请求头
  • 使用 IP 代理
  • 不固定的采集间隔时间

希望这篇文章对你有所帮助,下一篇是关于多线程爬虫的探索。如果你对爬虫感兴趣,不妨关注一波,相互学习,相互进步

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java实现的爬虫抓取图片并保存操作示例

    本文实例讲述了Java实现的爬虫抓取图片并保存操作.分享给大家供大家参考,具体如下: 这是我参考了网上一些资料写的第一个java爬虫程序 本来是想获取煎蛋网无聊图的图片,但是网络返回码一直是503,所以换了网站 import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStre

  • springboot+webmagic实现java爬虫jdbc及mysql的方法

    前段时间需要爬取网页上的信息,自己对于爬虫没有任何了解,就了解了一下webmagic,写了个简单的爬虫. 一.首先介绍一下webmagic: webmagic采用完全模块化的设计,功能覆盖整个爬虫的生命周期(链接提取.页面下载.内容抽取.持久化),支持多线程抓取,分布式抓取,并支持自动重试.自定义UA/cookie等功能. 实现理念: Maven依赖: <dependency> <groupId>us.codecraft</groupId> <artifactId

  • JAVA爬虫实现自动登录淘宝

    目的 想通过JAVA代码实现淘宝网的自动登录,通过获取设置的登录信息自动填写并提交.目前这个代码是小编测试过的,可以通过,后期不知道淘宝会不会有相应的封堵策略. 代码分享: package util; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.fi

  • JAVA使用HtmlUnit爬虫工具模拟登陆CSDN案例

    最近要弄一个爬虫程序,想着先来个简单的模拟登陆, 在权衡JxBrowser和HtmlUnit 两种技术,  JxBowser有界面呈现效果,但是对于某些js跳转之后的效果获取比较繁琐. 随后考虑用HtmlUnit, 想着借用咱们CSND的登陆练练手.谁知道CSDN的登陆,js加载时间超长,不设置长一点的加载时间,按钮提交根本没效果,js没生效. 具体看代码注释吧. 奉劝做爬虫的同志们,千万别用CSDN登陆练手,坑死我了. maven配置如下: <dependencies> <!-- ht

  • Java 爬虫如何爬取需要登录的网站

    这是 Java 网络爬虫系列博文的第二篇,在上一篇 Java 网络爬虫新手入门详解 中,我们简单的学习了一下如何利用 Java 进行网络爬虫.在这一篇中我们将简单的聊一聊在网络爬虫时,遇到需要登录的网站,我们该怎么办? 在做爬虫时,遇到需要登陆的问题也比较常见,比如写脚本抢票之类的,但凡需要个人信息的都需要登陆,对于这类问题主要有两种解决方式:一种方式是手动设置 cookie ,就是先在网站上面登录,复制登陆后的 cookies ,在爬虫程序中手动设置 HTTP 请求中的 Cookie 属性,这

  • Java 网络爬虫新手入门详解

    这是 Java 网络爬虫系列文章的第一篇,如果你还不知道 Java 网络爬虫系列文章,请参看Java 网络爬虫基础知识入门解析.第一篇是关于 Java 网络爬虫入门内容,在该篇中我们以采集虎扑列表新闻的新闻标题和详情页为例,需要提取的内容如下图所示: 我们需要提取图中圈出来的文字及其对应的链接,在提取的过程中,我们会使用两种方式来提取,一种是 Jsoup 的方式,另一种是 httpclient + 正则表达式的方式,这也是 Java 网络爬虫常用的两种方式,你不了解这两种方式没关系,后面会有相应

  • Java 网络爬虫基础知识入门解析

    前言 说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少.有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬虫而且还能做的非常好,在开源社区中有不少优秀的 Java 网络爬虫框架,例如 webmagic .我的第一份正式工作就是使用 webmagic 编写数据采集程序,当时参与了一个舆情分析系统的开发,这里面涉及到了大量网站的新闻采集,我们就使用了 webmagic 进行采集程序的编写,由于当时不知

  • java实现爬虫爬网站图片的实例代码

    第一步,实现 LinkQueue,对url进行过滤和存储的操作 import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; public class LinkQueue { // 已访问的 url 集合 private static Set<String> visitedUrl = Collecti

  • Java 爬虫服务器被屏蔽的解决方案

    这是 Java 爬虫系列博文的第四篇,在上一篇Java 爬虫数据异步加载如何解决,试试这两种办法! 中,我们从内置浏览器内核和反向解析法两个角度简单的聊了聊关于处理数据异步加载问题.在这篇文章中,我们简单的来聊一聊爬虫时,资源网站根据用户访问行为屏蔽掉爬虫程序及其对应的解决办法. 屏蔽爬虫程序是资源网站的一种保护措施,最常用的反爬虫策略应该是基于用户的访问行为.比如限制每台服务器在一定的时间内只能访问 X 次,超过该次数就认为这是爬虫程序进行的访问,基于用户访问行为判断是否是爬虫程序也不止是根据

  • 详解java爬虫jsoup解析多空格class数据

    在使用jsoup爬取其他网站数据的时候,发现class是带空格的多选择,如果直接使用doc.getElementsByClass("class的值"),这种方法获取不到想要的数据. 1.问题描述: 在使用jsoup爬取其他网站数据的时候,发现class是带空格的多选择,如果直接使用doc.getElementsByClass("class的值"),这种方法获取不到想要的数据. 爬取网站页面结构如下: 2.其中文章列表的div为:<div class="

  • Java Red5服务器实现流媒体视频播放

    引言 流媒体文件是目前非常流行的网络媒体格式之一,这种文件允许用户一边下载一边播放,从而大大减少了用户等待播放的时间.另外通过网络播放流媒体文件时,文件本身不会在本地磁盘中存储,这样就节省了大量的磁盘空间开销.正是这些优点,使得流媒体文件被广泛应用于网络播放. 流媒体服务器是通过建立发布点来发布流媒体内容和管理用户连接的.流媒体服务器能够发布从视频采集卡或摄像机等设备中传来的实况流,也可以发布事先存储的流媒体文件,并且发布实况流和流媒体文件的结合体.一个媒体流可以由一个媒体文件构成,也可以由多个

  • 图文精讲java常见分布式事务理论与解决方案

    目录 CAP理论 C(Consistence):一致性 A(Availability):可用性 P(Partition tolerance):分区容错性 BASE理论 BA(Basically Available):基本可用 S(Soft-state):软状态 E(Eventually Consistent):最终一致性 一致性hash Gossip协议 Gossip协议的特点: Raft算法 选举 复制 分布式事务 2PC 3PC TCC 如何解决某个节点故障的问题?如何解决数据一致性的问题?

  • Java爬虫Jsoup+httpclient获取动态生成的数据

    Java爬虫Jsoup+httpclient获取动态生成的数据 前面我们详细讲了一下Jsoup发现这玩意其实也就那样,只要是可以访问到的静态资源页面都可以直接用他来获取你所需要的数据,详情情跳转-Jsoup爬虫详解,但是很多时候网站为了防止数据被恶意爬取做了很多遮掩,比如说加密啊动态加载啊,这无形中给我们写的爬虫程序造成了很大的困扰,那么我们如何来突破这个梗获取我们急需的数据呢, 下面我们来详细讲解一下如何获取 String startPage="https://item.jd.com/1147

  • AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】

    本文实例讲述了AngularJS实现与Java Web服务器交互操作的方法.分享给大家供大家参考,具体如下: AngularJS是Google工程师研发的产品,它的强大之处不是几句话就能描述的,只有真正使用过的人才能体会到,笔者准备在这篇文章中,以一个简单的登录校验的例子说明如何使用AngularJs和Web服务器进行交互. 准备工作 1.下载angular js库. 官网下载地址:https://angularjs.org/ 或者点击此处本站下载. 2.开发环境准备,由于是和Tomcat服务器

  • Java 爬虫工具Jsoup详解

    Java 爬虫工具Jsoup详解 Jsoup是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址.HTML 文本内容.它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据. jsoup 的主要功能如下: 1. 从一个 URL,文件或字符串中解析 HTML: 2. 使用 DOM 或 CSS 选择器来查找.取出数据: 3. 可操作 HTML 元素.属性.文本: jsoup 是基于 MIT 协议发布的,可放心使用于商业项目. js

  • Java从服务器上获取时间动态显示在jsp页面实现思路

    Java获取服务器时间,动态显示到jsp页面,大家都是到Java只能获取一次,到页面的时间是静态的,不过通过js和Java的合作,巧妙地实现此功能. 本人是给电视做系统,客户要求页面能显示时间,因为电视浏览器获取的时间不对,没办法只能从服务器获取时间,但是问题来了,服务器的时间获取一次就成静态的了,客户不满意,但也没办法,只能这样.不过这个问题在我这老惦记着,今天看到有个例子,说把Java获取服务器的时间转化成毫秒,然后用js每一秒刷新一次就可以动态显示,所以就有了下面的 复制代码 代码如下:

  • 基于Java web服务器简单实现一个Servlet容器

    上篇写了一个简单的Java web服务器实现,只能处理一些静态资源的请求,本篇文章实现的Servlet容器基于前面的服务器做了个小改造,增加了Servlet请求的处理.  程序执行步骤  1.创建一个ServerSocket对象:  2.调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待:  3.从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应:

  • java 爬虫详解及简单实例

    Java爬虫 一.代码 爬虫的实质就是打开网页源代码进行匹配查找,然后获取查找到的结果. 打开网页: URL url = new URL(http://www.cnblogs.com/Renyi-Fan/p/6896901.html); 读取网页内容: BufferedReader bufr = new BufferedReader(new InputStreamReader(url.openStream())); 正则表达式进行匹配: tring mail_regex = "\\w+@\\w+

随机推荐