使用Jsoup抓取数据

问题

最近公司的市场部分布了一个问题,到一个网站截取一下医院的数据。刚好我也被安排做。后来,我发现为何不用脚本去抓取呢?
抓取的数据如下:
这里写图片描述

Jsoup的使用实战代码

结构

Created with Raphaël 2.1.0 开始 创建线程池 jsoup读取网页 解析Element 写入sqlite 结束
  • java代码
public class GetDoctorInfo {

    public GetDoctorInfo() {

        ExecutorService threadPool = Executors.newFixedThreadPool(5);

        //43有问题
        //73有问题

        for (int i = 1; i <= 100; i++) {
            String path = "http://so.haodf.com/index/search?type=hospitalfaculty&p=" + i + "&kw=%B8%BE%B2%FA%BF%C6";
            threadPool.execute(new GetDoctorRun(path));
        }

        threadPool.shutdown();

    }


    public static void main(String[] arg) {
        new GetDoctorInfo();
    }

    public static synchronized void printInfo(String sql) {
        System.out.println(sql);
    }

    public static String trans(String input) {
        String value;
        value = input.replaceAll("<td>", "").replaceAll("</td>", "").replaceAll("&nbsp;", "").replaceAll(" 地址地图:", "");
        return value;
    }


    /**
     * 获取医生的线程
     */
    public class GetDoctorRun implements Runnable {

        final String mURL;

        public GetDoctorRun(String mURL) {
            this.mURL = mURL;
        }

        @Override
        public void run() {
            try {
                Document doc = null;
                try {
//                    doc = (Document) Jsoup.parse(new URL("http://so.haodf.com/index/search?type=hospitalfaculty&p=99&kw=%B8%BE%B2%FA%BF%C6")
//                            , 1000);

                    doc = (Document) Jsoup.parse(new URL(mURL), 3000);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                //定位到列表
                Elements elements = doc.getElementsByClass("list");
                Elements childElements = elements.get(0).getAllElements();

                Element child = childElements.get(3);

                //获得所有的超链接的数据
                Elements aLinks = child.getElementsByTag("a");
                ArrayList<String> name = new ArrayList<>();
                ArrayList<String> address = new ArrayList<>();
                for (int i = 1; i <= aLinks.size(); i++) {
                    Element e = aLinks.get(i - 1);
                    if (e.attr("target").equals("_blank")) {
                        //排除 科室介绍
                        //排除 门诊时间
                        if (!e.text().equals("科室介绍") && !e.text().equals("门诊时间")) {

//                            System.out.println("--" + e.text());
                            if (i % 2 == 0) {
                                if (e.text().equals("") || e.text() == null) {
                                    address.add("");
                                } else {
                                    address.add(e.text());
                                }
                            } else {
                                if (e.text().equals("") || e.text() == null) {
                                    name.add("");
                                } else {
                                    name.add(e.text());
                                }
                            }
                        }
                    }
                }

                //将长连接的内容删除
                child.select("a").remove();
                child.select("span").remove();
                child.select("br").remove();

                String tran = trans(child.toString());

//                System.out.println(tran);


                String[] phones = tran.substring("     电  话:".length(), tran.length() - 1).split("电  话:");

                System.out.println();
                System.out.println();
                System.out.println();

                for (int i = 0; i < name.size(); i++) {

//                    System.out.println(phones[i]);

//                    //INSERT INTO info(hospital_name,address,phone) VALUES ('gg','hhh','ddd');

                    StringBuffer bufferValue = new StringBuffer("INSERT INTO info(hospital_name,address,phone) VALUES (");

                    //医院名
                    bufferValue.append("'").append(name.get(i)).append("'");
                    //医院地址
                    bufferValue.append(",'").append(address.get(i)).append("'");
                    //医院的电话
                    bufferValue.append(",'").append(phones[i].trim()).append("');");

                    printInfo(bufferValue.toString());
                }


                if (name.size() != 10) {
                    System.out.println("name==" + mURL);
                }
                if (address.size() != 10) {
                    System.out.println("address=" + mURL);
                }
                if (phones.length != 10) {
                    System.out.println("phone=" + phones.length + " " + mURL);

                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


}
  • Terminal写入sqlte

.open hospital.db
sqlite3 -init sql

总结

jsoup的使用很简单,有点像解析xml。不过结果很好的,因为5,6个人的工作就被这个简单的代码实现了。解析技巧有一个尽量清除不必要的标签。如代码:

       child.select("a").remove();
       child.select("span").remove();
       child.select("br").remove();
  • 学会用脚本收集数据
  • 注意多谢线程并发的安全,要检验,要不很易出错
  • 对于多线程的问题关键是要确保你的内容不被竞争弄乱,所以提取出来进行代码块是很重要的。

最后补充一下最终的效果如下图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值