精华内容
下载资源
问答
  • Java数据爬取

    2020-04-01 14:17:16
    它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据,用Java写爬虫的同行们十之八九用过我。为什么呢?因为我在这个方面功能强大、使用方便。不信的话,可以继续往下看,代码是...

    一、Jsoup自我介绍

    大家好,我是Jsoup。

    我是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据,用Java写爬虫的同行们十之八九用过我。为什么呢?因为我在这个方面功能强大、使用方便。不信的话,可以继续往下看,代码是不会骗人的。

    二、目标内容(虎扑足球,社区热点这一块的标题https://soccer.hupu.com/)

    在这里插入图片描述

    三、两行代码搞定(轻松愉快)

    在这里插入图片描述

        @Test
        void Test() throws  IOException {
            Jsoup.connect("https://soccer.hupu.com/").get().body().getElementsByClass("list-area-main-infinite-item-content-title").forEach(e->{
                    System.err.println(e.text());
                });
    
        }
    

    依赖

       <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.12.1</version>
            </dependency>
    

    四、至于为什么代码这么写?Jsoup原理?怎么分析网站?反爬虫怎么办?

    百度就完事了。
    灵感基于:
    https://www.cnblogs.com/sam-uncle/p/10922366.html
    https://www.open-open.com/jsoup/

    展开全文
  • Java数据爬取——爬取携程酒店数据(一) 2016年11月23日 15:29:38 贾小牛 阅读数:8107 ...

    Java数据爬取——爬取携程酒店数据(一)

    最近工作要收集点酒店数据,就到携程上看了看,记录爬取过程去下

    1.根据城市名称来分类酒店数据,所以先找了所有城市的名称
    在这个网页上有http://hotels.ctrip.com/domestic-city-hotel.html

    这里写图片描述

    从网站地图上可以很容易发现这个页面

    2.然后查看源码

    这里写图片描述

    发现所有需要的数据都在

    <dl class = "pinyin_filter_detail layoutfix"></dl>
    • 1

    3.我们获取一下dl 这个元素和其中的所有子元素

    我们用jsoup的jar包来解析获取的html,官网https://jsoup.org/,有API和jar包

    String result = HttpUtil.getInstance().httpGet(null, "http://hotels.ctrip.com/domestic-city-hotel.html");
    Document root_document = Jsoup.parse(result);
    Elements pinyin_filter_elements = root_document.getElementsByClass("pinyin_filter_detail layoutfix");
    
    //包含所有城市的Element
    Element pinyin_filter = pinyin_filter_elements.first();
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.我准备把获取的城市数据存储到mysql中,所以下面连接了本地mysql数据库

    // 连接数据库
    Connection conn = SqlDBUtils.getConnection();
    StringBuilder create_table_sql = new StringBuilder();
    create_table_sql.append("create table if not exists ctrip_hotel_city (id integer primary key auto_increment, city_id integer not null, city_name varchar(255) not null, head_pinyin varchar(80) not null, pinyin varchar(255) not null)");
    PreparedStatement preparedStatement;
    try {
        //每次执行删除一下表,防止数据插入重复
        preparedStatement = conn.prepareStatement("DROP TABLE IF EXISTS ctrip_hotel_city");
        preparedStatement.execute();
        // 创建ctrip_hotel_city表,存储城市数据
        preparedStatement = conn.prepareStatement(create_table_sql.toString());
        preparedStatement.execute();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5.获取dl下所有的dt和dd,并从中提取数据库表中所需要的字段,实现存储

    //拼音首字符Elements
    Elements pinyins = pinyin_filter.getElementsByTag("dt");
    //所有dd的Elements
    Elements hotelsLinks = pinyin_filter.getElementsByTag("dd");
    • 1
    • 2
    • 3
    • 4

    6.数据提取

    for (int i = 0; i < pinyins.size(); i++) {
        Element head_pinyin = pinyins.get(i);
        Element head_hotelsLink = hotelsLinks.get(i);
        Elements links = head_hotelsLink.children();
        for (Element link : links) {
            String cityId = StringUtil.getNumbers(link.attr("href"));
            String cityName = link.html();
            String head_pinyin_str = head_pinyin.html();
            String pinyin_cityId = link.attr("href").replace("/hotel/", "");
            String pinyin = pinyin_cityId.replace(StringUtil.getNumbers(link.attr("href")), "");
            StringBuffer insert_sql = new StringBuffer();
            insert_sql.append("insert into ctrip_hotel_city (city_id, city_name, head_pinyin, pinyin) values (");
            insert_sql.append(cityId);
            insert_sql.append(", '" + cityName + "'");
            insert_sql.append(", '" + head_pinyin_str + "'");
            //此处注意汉语拼音中会有',直接插入数据库会报错,要把一个'替换为两个''
            insert_sql.append(", '" + pinyin.replace("'", "''") + "')");
            try {
                preparedStatement = conn.prepareStatement(insert_sql.toString());
                preparedStatement.execute();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    7.运行后查看mysql数据库ctrip_hotel_city表,如下

    这里写图片描述

    至此,酒店城市获取思路已介绍完毕,下面将介绍怎么用城市获取城市所有酒店的数据,
    github源码地址 https://github.com/jianiuqi/CTripSpider
    博文Java数据爬取——爬取携程酒店数据(二) 中介绍了如何利用地区爬取酒店数据,并保存到了mysql数据库

    展开全文
  • 在上篇文章Java数据爬取——爬取携程酒店数据(一)爬取所有地区后,继续根据地区数据爬取酒店数据1.首先思考怎样根据地域获取地域酒店信息,那么我们看一下携程上是怎样获得的。 还是打开...

    在上篇文章Java数据爬取——爬取携程酒店数据(一)爬取所有地区后,继续根据地区数据爬取酒店数据

    1.首先思考怎样根据地域获取地域酒店信息,那么我们看一下携程上是怎样获得的。
    还是打开http://hotels.ctrip.com/domestic-city-hotel.html 这个地址,随便点击一个地区进去(这里我选取澳门作为示例),点击第二页数据,很高兴发现

    这里写图片描述

    http://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx 传递参数给这个Url可以得到酒店数据

    2.模拟请求,获取数据

    这里写图片描述

    从这里可以发现,是POST请求,请求的body中有很多参数,

    这里写图片描述

    所以先封装一下参数,经过测试,有些参数可以不用传递,这里写了一个方法,模拟请求

    public String getHotelListString(HotelCity city, String page){
            HashMap<String, String> params = new HashMap<String, String>();
            params.put("__VIEWSTATEGENERATOR", "DB1FBB6D");
            params.put("cityName", city.getCityName());
    //      params.put("StartTime", "2016-11-24");
    //      params.put("DepTime", "2016-11-25");
            params.put("txtkeyword", "");
            params.put("Resource", "");
            params.put("Room", "");
            params.put("Paymentterm", "");
            params.put("BRev", "");
            params.put("Minstate", "");
            params.put("PromoteType", "");
            params.put("PromoteDate", "");
            params.put("operationtype", "NEWHOTELORDER");
            params.put("PromoteStartDate", "");
            params.put("PromoteEndDate", "");
            params.put("OrderID", "");
            params.put("RoomNum", "");
            params.put("IsOnlyAirHotel", "F");
            params.put("cityId", city.getCityId());
            params.put("cityPY", city.getPinyin());
    //      params.put("cityCode", "1853");
    //      params.put("cityLat", "22.1946");
    //      params.put("cityLng", "113.549");
            params.put("positionArea", "");
            params.put("positionId", "");
            params.put("keyword", "");
            params.put("hotelId", "");
            params.put("htlPageView", "0");
            params.put("hotelType", "F");
            params.put("hasPKGHotel", "F");
            params.put("requestTravelMoney", "F");
            params.put("isusergiftcard", "F");
            params.put("useFG", "F");
            params.put("HotelEquipment", "");
            params.put("priceRange", "-2");
            params.put("hotelBrandId", "");
            params.put("promotion", "F");
            params.put("prepay", "F");
            params.put("IsCanReserve", "F");
            params.put("OrderBy", "99");
            params.put("OrderType", "");
            params.put("k1", "");
            params.put("k2", "");
            params.put("CorpPayType", "");
            params.put("viewType", "");
    //      params.put("checkIn", "2016-11-24");
    //      params.put("checkOut", "2016-11-25");
            params.put("DealSale", "");
            params.put("ulogin", "");
            params.put("hidTestLat", "0%7C0");
    //      params.put("AllHotelIds", "436450%2C371379%2C396332%2C419374%2C345805%2C436553%2C425997%2C436486%2C436478%2C344977%2C5605870%2C344983%2C371396%2C344979%2C2572033%2C699384%2C425795%2C419823%2C2010726%2C5772619%2C1181591%2C2005951%2C345811%2C371381%2C371377");// TODO
            params.put("psid", "");
            params.put("HideIsNoneLogin", "T");
            params.put("isfromlist", "T");
            params.put("ubt_price_key", "htl_search_result_promotion");
            params.put("showwindow", "");
            params.put("defaultcoupon", "");
            params.put("isHuaZhu", "False");
            params.put("hotelPriceLow", "");
            params.put("htlFrom", "hotellist");
            params.put("unBookHotelTraceCode", "");
            params.put("showTipFlg", "");
    //      params.put("hotelIds", "436450_1_1,371379_2_1,396332_3_1,419374_4_1,345805_5_1,436553_6_1,425997_7_1,436486_8_1,436478_9_1,344977_10_1,5605870_11_1,344983_12_1,371396_13_1,344979_14_1,2572033_15_1,699384_16_1,425795_17_1,419823_18_1,2010726_19_1,5772619_20_1,1181591_21_1,2005951_22_1,345811_23_1,371381_24_1,371377_25_1");// TODO
            params.put("markType", "1");
            params.put("zone", "");
            params.put("location", "");
            params.put("type", "");
            params.put("brand", "");
            params.put("group", "");
            params.put("feature", "");
            params.put("equip", "");
            params.put("star", "");
            params.put("sl", "");
            params.put("s", "");
            params.put("l", "");
            params.put("price", "");
            params.put("a", "0");
            params.put("keywordLat", "");
            params.put("keywordLon", "");
            params.put("contrast", "0");
            params.put("page", page);
            params.put("contyped", "0");
            params.put("productcode", "");
            String result = HttpUtil.getInstance().httpPost(hotelUrl, params);
            // 数据中有转义符直接转JSON报错,所以这里重新拼接所需要的JSON数据
            String tempHotel = result.substring(result.indexOf("hotelPositionJSON")-1, result.length());
            // 确保截取到indexOf("biRecord"), 减2是因为需要]符号
            String hotelArray = tempHotel.substring(0, tempHotel.indexOf("biRecord") - 2);
            String tempTotalCount = result.substring(result.indexOf("hotelAmount")-1, result.length());
            String totalCount = tempTotalCount.substring(0, tempTotalCount.indexOf(","));
            StringBuffer sb = new StringBuffer();
            sb.append("{");
            sb.append(totalCount);
            sb.append(",");
            sb.append(hotelArray);
            sb.append("}");
            return sb.toString().replace("\\", "");
        }

    说明:这个方法对返回结果进行了操作,直接把hotelPositionJSON和hotelAmount的内容提取了出来(因为直接转换时发现数据中含有转义符导致转为JSON失败),操作后的数据格式为:

    {
        "hotelAmount": 11265,
        "hotelPositionJSON": [
            {
                "id": "6297824",
                "name": "北京浣川招待所",
                "lat": "39.918086",
                "lon": "116.427508",
                "url": "/hotel/6297824.html?isFull=F#ctm_ref=hod_sr_map_dl_txt_1",
                "img": "http://pic.c-ctrip.com/hotels110127/hotel_example.jpg",
                "address": "东城区东城区外交部街46号-1。 ( 北京站、建国门地区)",
                "score": "0.0",
                "dpscore": "0",
                "dpcount": "0",
                "star": "hotel_diamond01",
                "stardesc": "携程用户评定为1钻",
                "shortName": "",
                "isSingleRec": "false"
            },
            {
                "id": "6298279",
                "name": "北京怀柔喇叭沟门海燕农家院",
                "lat": "40.956471",
                "lon": "116.513108",
                "url": "/hotel/6298279.html?isFull=F#ctm_ref=hod_sr_map_dl_txt_2",
                "img": "http://pic.c-ctrip.com/hotels110127/hotel_example.jpg",
                "address": "怀柔区黄甸子村。 ( 怀柔风景区)",
                "score": "0.0",
                "dpscore": "0",
                "dpcount": "0",
                "star": "hotel_diamond01",
                "stardesc": "携程用户评定为1钻",
                "shortName": "",
                "isSingleRec": "false"
            }
        ]
    }

    3.循环遍历城市数据,查询每个城市的酒店即可

    long startTime = System.currentTimeMillis();
    HotelCitySpider citySpider = new HotelCitySpider();
    HotelSpider spider = new HotelSpider();
    List<HotelCity> cities = citySpider.getHotelCities();
    long getCityTime = System.currentTimeMillis();
    System.out.println("获取城市所用时间(ms):" + (getCityTime - startTime));
    spider.createTable();
    for (HotelCity hotelCity : cities) {
        spider.saveHotels(hotelCity, spider.getHotelList(hotelCity));
    }
    long saveHotelTime = System.currentTimeMillis();
    System.out.println("获取酒店并存储所用时间(ms):" + (saveHotelTime - startTime));

    这里我仍然将数据存储到数据库中

    4.批量插入数据

    /**
         * 保存每个城市的酒店列表
         * @param city
         * @param hotels
         */
        public void saveHotels(HotelCity city, List<Hotel> hotels) {
            for (Hotel hotel : hotels) {
                StringBuffer insert_sql = new StringBuffer();
                insert_sql.append("insert into ctrip_hotel "
                        + "(hotel_id, city_id, city_name, name, lat, lon, url, img, address, score, dpscore, dpcount, star, stardesc, shortName, isSingleRec) values (");
                insert_sql.append("'" + hotel.getId() + "'");
                insert_sql.append(", " + city.getCityId());
                insert_sql.append(", '" + city.getCityName() + "'");
                insert_sql.append(", '" + hotel.getName() + "'");
                insert_sql.append(", " + hotel.getLat());
                insert_sql.append(", " + hotel.getLon());
                insert_sql.append(", '" + hotel.getUrl() + "'");
                insert_sql.append(", '" + hotel.getImg() + "'");
                insert_sql.append(", '" + hotel.getAddress() + "'");
                insert_sql.append(", " + hotel.getScore());
                insert_sql.append(", " + hotel.getDpscore());
                insert_sql.append(", " + hotel.getDpcount());
                insert_sql.append(", '" + hotel.getStar() + "'");
                insert_sql.append(", '" + hotel.getStardesc() + "'");
                insert_sql.append(", '" + hotel.getShortName() + "'");
                insert_sql.append(", " + hotel.getIsSingleRec() + ")");
                try {
                    preparedStatement = conn.prepareStatement(insert_sql.toString());
                    preparedStatement.execute();
                } catch (Exception e) {
                    e.getMessage();
                    continue;
                }
            }
        }

    原本想批量插入,但是数据有重复的hotel_id,preparedStatement.executeBatch()会报错,所以还是一条条插入。
    github源码地址 https://github.com/jianiuqi/CTripSpider

    展开全文
  • 利用java定时爬取网页数据,完整爬取数据源码及jar,利用java定时爬取网页数据,可自行导入到本地测试,仅供参考
  • java爬虫爬取数据

    2018-05-04 16:48:51
    利用HTML工具,多线程,消息队列,模拟浏览器实现爬取网页数据
  • java网页数据爬取

    2018-03-10 23:50:00
    java网页数据爬取 写在前面 书签全部导出 爬取前的处理 开始爬取并保存 java网页数据爬取 写在前面 在浏览器书签中有许多经典的东西,有时候什么忘记了需要去查询的,也非常方便,但是痛苦的事情是某一...

    java网页数据爬取

    写在前面

    在浏览器书签中有许多经典的东西,有时候什么忘记了需要去查询的,也非常方便,但是痛苦的事情是某一天打开书签,居然那个页面不知道飞哪去了,打不开,作为一个程序员,当然不能容忍这种事情发生,那就把它们都爬下来。

    书签全部导出

    以chrome浏览器为例:打开右上角三个点,设置项,找到书签,选择书签管理器,打开后点击整理下拉列表,有将书签导出到html文件选项,导出即可。

    爬取前的处理

    首先我们的书签可能有几种分类,为了处理方便,可以手动删除我们不需要的,也可以程序处理一下;以下处理是为了爬取方便,而不是删除不想要的。
    先来看看导出的html文件的结构:

    <!DOCTYPE NETSCAPE-Bookmark-file-1>
    <!-- This is an automatically generated file.
         It will be read and overwritten.
         DO NOT EDIT! -->
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
    <TITLE>Bookmarks</TITLE>
    <H1>Bookmarks</H1>
    <DL><p>
        <DT><H3 ADD_DATE="1481295500" LAST_MODIFIED="1520685941" PERSONAL_TOOLBAR_FOLDER="true">书签栏</H3>
        <DL><p>
            <DT><A HREF="http://fanyi.baidu.com/?aldtype=16047#auto/zh" ADD_DATE="1481296188" ICON="data:image/png;base64,******">百度翻译</A>
            <DT><A HREF="http://www.iciba.com/?=2016pcChromebookmark" ADD_DATE="1483001064" ICON="data:image/png;base64,******">爱词霸在线词典</A>
            <DT><H3 ADD_DATE="1520685896" LAST_MODIFIED="1520694188">学习</H3>
            <DL><p>
                <DT><A HREF="https://www.csdn.net/" ADD_DATE="1520694161" ICON="data:image/png;base64,******">CSDN-专业IT技术社区</A>
                <DT><A HREF="https://www.oschina.net/" ADD_DATE="1520694188" ICON="data:image/png;base64,******">开源中国 - 找到您想要的开源项目,分享和交流</A>
            </DL><p>
        </DL><p>
    </DL><p>

    在导出的数据中,base64,*,本来是一长串的字符,为了节省篇幅,我用*代替了。如上面导出的结果,有两种分类,一种是默认的(百度翻译和爱词霸在线词典),一种是在学习分类下(CSDN-专业IT技术社区和开源中国找到您想要的开源项目,分享和交流),一般想保存的肯定是学习下的,所以需要手动删除不需要的,我在这就不删除了,直接把上面所有的链接上的数据都拔下来。

    InputStreamReader reader = null;
            BufferedReader br = null;
            StringBuffer stringBuffer =new StringBuffer("");
            try {
                br = new BufferedReader (new InputStreamReader (new FileInputStream (data), ENCODE));       
                String line  = br.readLine();  
                while (line != null) {
                    if(line.trim().startsWith("<DT><A")){
                        stringBuffer.append(line.replaceAll("<DT>", ""));
                    }
                    line = br.readLine(); // 一次读入一行数据  
                } 
            }  catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if(reader!=null){
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(br!=null){
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

    好了,数据处理完毕,
    处理结果如下

    <A HREF="http://fanyi.baidu.com/?aldtype=16047#auto/zh" ADD_DATE="1481296188" ICON="data:image/png;base64,******">百度翻译</A>        <A HREF="http://www.iciba.com/?=2016pcChromebookmark" ADD_DATE="1483001064" ICON="data:image/png;base64,******">爱词霸在线词典</A>            <A HREF="https://www.csdn.net/" ADD_DATE="1520694161" ICON="data:image/png;base64,******">CSDN-专业IT技术社区</A>            <A HREF="https://www.oschina.net/" ADD_DATE="1520694188" ICON="data:image/png;base64,******">开源中国 - 找到您想要的开源项目,分享和交流</A>

    还是将多余字符用**代替

    开始爬取并保存

        private static void parser(StringBuffer stringBuffer) {
            try{
                    Parser parser = new Parser(stringBuffer.toString());//构造解析对象
                    parser.setEncoding(ENCODE);//设置编码UTF-8
                    for (NodeIterator i = parser.elements (); i.hasMoreNodes(); ) {
                        final Node node = i.nextNode();
                        if(node.getText().contains("A HREF")){
                            if (node instanceof CompositeTag){
                                NetWork net = new NetWork();
                                /**获得链接并保存数据**/
                                net.getData(((CompositeTag)node).getAttribute("HREF"), new NetResult() {
    
                                    @Override
                                    public void onSuccess(String cache, String body,String data) {
                                        //System.out.println(data);
                                        String path = ((CompositeTag)node).getStringText();
                                        path = path.replaceAll("[\\s\\\\/:\\*\\?\\\"<>\\|]","");//处理特殊字符
                                        System.out.println("path:"+path);
                                        if(path==null||path.isEmpty()){
                                            path = "未命名";
                                        }
                                        FileUtil.stringToFile(data, "F:\\"+path+".html");//保存文件
    
                                    }
    
                                    @Override
                                    public void onFailure() {
    
                                    }
                                });
    
                            }
                            else
                            {
                                System.out.println(node.getText());
                            }
                        }
                    }          
                }
                catch( Exception e ) {     
                    System.out.println( "Exception:"+e );
                }
        }

    数据保存完毕,再也不用担心数据丢失了(只是实现了一点功能,保存文字,并没有保存图片和js\css文件,以后有时间了继续)。

    展开全文
  • 昨天才发现原来不止python可以爬数据JAVA也可以。JAVA果然是世界上最好的语言。哈哈哈哈哈哈哈。 进入正题。 首先自己建一个MAVEN项目 怎么建就不说了,直接贴依赖了。 <dependency>...
  • Java爬虫爬取网页数据

    千次阅读 多人点赞 2019-11-20 16:28:00
    Java爬虫爬取网页数据 一.简单介绍爬虫 网络爬虫(Web Crawler),又称为网络蜘蛛(Web Spider)或 Web 信息采集器,是一种按照一定规则,自动抓取或下载网络信息的计算机程序或自动化脚本,是目前搜索引擎的重要...
  • Java-爬取页面数据

    2019-09-04 09:28:57
    Java-爬取页面数据 public class HttpReptilianUtil { public static String getHtml(String url){ BufferedReader in = null; //定义字符缓冲区 StringBuffer stringBuffer = new StringBuffer(); try { //...
  • Java实现爬取京东手机...项目没什么太难的地方,就是考验你对HTML源码的解析,层层解析,同标签选择器seletor进行元素筛选,再结合HttpCLient技术,成功把手机数据爬取下来。 一、项目Maven环境配置 1、配置SpringB...
  • java爬虫爬取插件数据

    2017-10-23 02:43:46
    请问一下各位大神, java爬虫可以爬取插件数据么? 求各位大神指点一下。 可以的话能把思路告诉我么?
  • Java定时爬取数据

    2019-01-15 14:52:51
    刚刚入职一家教育机构,被要求爬取一些学校的新闻到数据库来丰富公司对外系统的页面丰富性,接下来是一些简单的教程。 一.配置文件 applicationContent如下 &lt;?xml version="1.0" encoding="...
  • 所以就想能不能用java实现一个爬虫,百度搜索发现,其实java也有很多优秀得开源爬虫框架,包括Gecco,webmagic,Jsoup等等非常多得优秀开源框架,可以让我们在不是十分熟悉正则表达式得情况下也能实现爬虫爬取数据。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,810
精华内容 724
关键字:

java数据爬取

java 订阅