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中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推