java爬虫-------爬取携程景点及门票数据

2023-10-10 21:50

本文主要是介绍java爬虫-------爬取携程景点及门票数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.爬虫

    1. 网络爬虫简介

   他的主要工作就是 跟据指定的url地址 去发送请求,获得响应, 然后解析响应 , 一方面从响应中查找出想要查找的数据,另一方面从响应中解析出新的URL路径,然后继续访问,继续解析;继续查找需要的数据和继续解析出新的URL路径  .

这就是网络爬虫主要干的工作.  下面是流程图:

    1. 爬虫准备

通过上面的流程图 能大概了解到 网络爬虫 干了哪些活  ,根据这些 也就能设计出一个简单的网络爬虫出来.

 

一个简单的爬虫 必需的功能:  

 

1: 发送请求和获取响应的功能 ;

 

2: 解析响应的功能 ;

 

3: 对 过滤出的数据 进行存储 的功能 ;

 

4: 对解析出来的URL路径 处理的功能 ;

2.java爬虫

2.1实现java爬虫的三种简易方式

  1. 通过urlconnection抓取信息:

步骤:
1.获取url
2.获取http请求
3.获取状态码
4.根据状态吗返回信息。

代码:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class ConnectionUtil {

    public static String Connect(String address){
        HttpURLConnection conn = null;
        URL url = null;
        InputStream in = null;
        BufferedReader reader = null;
        StringBuffer stringBuffer = null;
        try {
            //1.新建url对象,表示要访问的网页
            url = new URL(address);
            //2.建立http连接,返回连接对象urlconnection
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setDoInput(true);
            conn.connect();

            //3.获取相应的http状态码,
            int code=conn.getResponseCode();
            if(code!=200){
                return null;
            }
            //4.如果获取成功,从URLconnection对象获取输入流来获取请求网页的源代码
            in = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(in));
            stringBuffer = new StringBuffer();
            String line = null;
            while((line = reader.readLine()) != null){
                stringBuffer.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            conn.disconnect();
            try {
                in.close();
                reader.close();
            } catch (Exception e) {
                System.out.println("获取不到网页源码:"+e);
                e.printStackTrace();
            }
        }

        return stringBuffer.toString();
    }
}

 

  1. 通过httpclient抓取信息:

引入pom依赖

<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

 

步骤
1.创建一个客户端,类似打开一个浏览器
2./创建一个get方法,类似在浏览器中输入一个地址,path则为URL的值
3.获得响应的状态码
4.得到返回的类容
5.释放资源

代码:

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Created by Administrator on 2018/8/7.
 */
public class HttpClient3 {

    public static String doGet(String url) {
        // 输入流
        InputStream is = null;
        BufferedReader br = null;
        String result = null;
        // 创建httpClient实例
        HttpClient httpClient = new HttpClient();
        // 设置http连接主机服务超时时间:15000毫秒
        // 先获取连接管理器对象,再获取参数对象,再进行参数的赋值
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(15000);
        // 创建一个Get方法实例对象
        GetMethod getMethod = new GetMethod(url);
        // 设置get请求超时为60000毫秒
        getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 60000);
        // 设置请求重试机制,默认重试次数:3次,参数设置为true,重试机制可用,false相反
        getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, true));
        try {
            // 执行Get方法
            int statusCode = httpClient.executeMethod(getMethod);
            // 判断返回码
            if (statusCode != HttpStatus.SC_OK) {
                // 如果状态码返回的不是ok,说明失败了,打印错误信息
                System.err.println("Method faild: " + getMethod.getStatusLine());
            } else {
                // 通过getMethod实例,获取远程的一个输入流
                is = getMethod.getResponseBodyAsStream();
                // 包装输入流
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                // 读取封装的输入流
                String temp = null;
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp).append("\r\n");
                }

                result = sbf.toString();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 释放连接
            getMethod.releaseConnection();
        }
        return result;
    }
    
    
    public static void main(String[] args){
        String s=doGet("http://www.baidu.com");
    }
}

 

3.通过jsoup获取网页信息:

引入jsoup jar包或maven依赖

<dependency>
   <!-- jsoup HTML parser library @ https://jsoup.org/ -->
   <groupId>org.jsoup</groupId>
   <artifactId>jsoup</artifactId>
   <version>1.11.3</version>
</dependency>

 

import java.io.File;
import java.io.IOException;


import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Created by Administrator on 2018/7/31.
 */
public class spider {
    public static void main(String[] args) throws IOException {
        String url = "http://www.baidu.com";
        Document document = Jsoup.connect(url).timeout(3000).get();


//通过Document的select方法获取属性结点集合
        Elements elements = document.select("a[href]");
//得到节点的第一个对象
        Element element = elements.get(0);
        System.out.println(element);

    }

}

 

3.java爬虫案例

3.1爬取百度上的所有链接

1.使用正则表达式进行信息提取

首先建立urlconnection连接获取网页返回的数据,然后使用正则表达式提取所有的 http链接地址

快速学习正则https://www.jb51.net/tools/zhengze.html

 

import java.io.BufferedReader;

import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class WebSpider {
    public static void main(String[] args) {
        URL url = null;
        URLConnection urlconn = null;
        BufferedReader br = null;
       // PrintWriter pw = null;

        try {
            //通过url建立与网页的连接
            url = new URL("http://www.baidu.com/");
            urlconn = url.openConnection();
            //pw = new PrintWriter(new FileWriter("f:/url(baidu).txt"), true);//这里我把爬到的链接存储在了F盘底下的一个叫做url(baidu)的doc文件中
            //通过链接取得网页返回的数据
            br = new BufferedReader(new InputStreamReader(urlconn.getInputStream()));
            String buf = null;
            StringBuffer stringBuffer = new StringBuffer();
            while ((buf = br.readLine()) != null) {
                stringBuffer.append(buf);
            }
            System.out.println("获取成功!"+stringBuffer);
            //编写获取http链接的正则表达式
            String regex = "http://[\\w+\\.?/?]+\\.[A-Za-z]+";
            Pattern p = Pattern.compile(regex);
            //匹配返回的结果
            Matcher m=p.matcher(stringBuffer.toString());
            while(m.find()){//查找匹配的链接
                String a=m.group();
                System.out.println("====爬取的链接"+a);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
           // pw.close();
        }
    }
}

 

 

 

 

 

 

2.使用jsoup解析遍历

Jsonp学习地址:html:http://www.open-open.com/jsoup/dom-navigation.htm

//使用http的get方式获取返回的网页信息
HttpClient h=new JavaHttpClient();
String s = h.doGet("http://www.baidu.com",null).getResponseString();
//System.out.println("======"+s);
Document root_document = Jsoup.parse(s);//将html的字符串解析成一个html文档
//获取所有a标签元素
Elements e=root_document.getElementsByTag("a");
//循环获取a标签的href属性
for(int i=0;i<e.size();i++){
    Element href=e.get(i);//得到每一个a标签
    String link=href.attr("href");//获取href属性
    System.out.println("====获取到的链接:"+link);
}

3.2爬取携程上的景点信息

1.首先进去携程页面,我需要爬取的是杭州的景点信息如图,点击搜索杭州,会看到以下的景点信息。

2.查看网页信息,使用谷歌的浏览器debug模式,也就是f12 我们先观察网页的布局检查元素寻找需要爬取到的信息。

3.通过查看发现所需要的数据都在<div id="searchResultContainer" class="searchresult_left"> 这个div中

我们获取一下这个div,使用jsonp的dom操作获取,获取之后在获取景点列表,可以看到列表景点的样式为searchresult_product04(在执行过程中发现样式除了04外还有searchresult_product05 所以我合并了两个集合)

HttpClient h=new JavaHttpClient();
String s = h.doGet(strurl,null).getResponseString();//自己写的一个http链接
Document root_document = Jsoup.parse(s);
//获取需要数据的div
Element e= root_document.getElementById("searchResultContainer");
//得到网页上的景点列表(包含两个样式集合)
Elements yy = e.getElementsByClass("searchresult_product04");
Elements yy2 = e.getElementsByClass("searchresult_product05");
yy.addAll(yy2);
System.out.println("-------------------------------------"+yy.size());

4.对获得的景点列表进行遍历获取每一个景点信息

使用jsoup的选择器进行信息抽取(使用方法可以利用谷歌的selectort)定位标题所在地方,鼠标右键copy->copy selector

得到#searchResultContainer > div:nth-child(1) > div > div.search_ticket_title > h2 > a

使用jsoup的select选择器 因为我们已经获取到了这个searchResultContainer div对象,所以直接用searchResultContainer 获取的对象像下级进行获取

Element nameStr=Info.selectFirst("div > div.search_ticket_title > h2 > a");

 

for(int i=0;i<yy.size();i++){
    //得到每一条景点信息
    Element Info=yy.get(i);
    //分析网页得到景点的标题(使用选择器语法来查找元素)
    Element nameStr=Info.selectFirst("div > div.search_ticket_title > h2 > a");
    String name=nameStr.html();//得到标题的信息
    String link=nameStr.attr("href");//得到标题的链接(可以存库对详情信息获取)
    Element gradeStr=Info.selectFirst(" div > div.search_ticket_title > h2 > span > span.rate");//得到景点等级
    String  grade=gradeStr.html();
    Element addressStr=Info.selectFirst("div > div.search_ticket_title > div.adress");//得到景点地址
    String address=addressStr.html();
    Element scoreStr=Info.selectFirst("div > div.search_ticket_assess > span.grades > em");//得到评分
    String score=null;
    if(scoreStr!=null){
        score=scoreStr.html();
    }
    Element judenumber=Info.selectFirst("div > div.search_ticket_assess > span.grades");//得到评论人数
    String judenum="";
    if(judenumber!=null){
        judenum=judenumber.text();//----分(3580人点评)
        //使用正则表达式抽取评论人数
        Pattern p=Pattern.compile("\\(.*人点评\\)");
        Matcher m=p.matcher(judenum);
        if(m.find()){
            judenum=m.group();
        }
    }
    Element specialStr=Info.selectFirst("div > div.search_ticket_title > div.exercise");//得到特色
    String special=specialStr.html();
    grade=("").equals(grade)?null:grade;
    //获取的地址是这样的 ----》地址:浙江省湖州市安吉县递铺镇天使大道1号  所以需要进行截取操作
    address=("").equals(address)?null:address.substring(address.indexOf(":")+1);
    special=("").equals(special)?null:special.substring(special.indexOf(":")+1);
    judenum=("").equals(judenumber)?null:Utils.getNum(judenum);
    System.out.println("==="+name);

    //组装成对象
    Object[] o=new Object[8];
    o[0]=name;
    o[1]=address;
    o[2]=score;
    o[3]=judenum;
    o[4]="杭州";
    o[5]=grade;
    o[6]=special;
    o[7]=link;
    insertqueue2.add(o);//加入队列进行入库
}

 

5.组装的对象进行入库操作

 

 

 

 

这篇关于java爬虫-------爬取携程景点及门票数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/183314

相关文章

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

MyBatis-Plus通用中等、大量数据分批查询和处理方法

《MyBatis-Plus通用中等、大量数据分批查询和处理方法》文章介绍MyBatis-Plus分页查询处理,通过函数式接口与Lambda表达式实现通用逻辑,方法抽象但功能强大,建议扩展分批处理及流式... 目录函数式接口获取分页数据接口数据处理接口通用逻辑工具类使用方法简单查询自定义查询方法总结函数式接口

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red