java的简单爬虫

印言
之前没有写过爬虫,最近被学长压迫,所以迅速学习了一波爬虫,这个过程十分的痛苦。
之前自己也没有发博客的习惯,- -仿佛发博客是上个世纪的事情,之前也有很多技术学习,但没有放到博客上。
希望以后学了什么技术可以发上来,既加深自己的印象,还帮助了大众。

  • 其实java的爬虫也没有那么难,之前刚刚大一的时候以为爬虫只有python有,十分的low。

  • 本质还是发HTTP请求,最简单的直接爬取页面,对于没有做反爬技术的网站还是很简单的。

  • 只要是用HttpClient这个库基本上就够了,然后解析HTML使用Jsoup。

  • 当然在学习的过程中发现了webmagic的爬虫框架,很庆幸是国人写的。

    • 但是感觉那个框架目前对非Http get的请求的支持并不是那么好。(时间坐标2017.11.6)
    • 相信这个框架会不断完善。
  • 接下来说一说我爬取过程中遇到的坑。

    • 我爬取了我们学校教务处的网站,说教务处,相信绝大多数都是相同的那一套。
    • 第一个坑就是编码的坑,教务处编码采用GB2312,HttpClient默认采用UTF-(当然,中间还尝试了OkHttp),相比之下我觉得HttpClient对编码的处理更适合我。
    • 第二个坑就是C#的坑,教务处的网站用.Net开发,由于我只懂java,一开始以为那个__viewstate是个不怎么重要的参数,但其实不然,如果post的__viewstate不正确,
      返回码虽然是302(登录成功),但是response header里面的location却会把你定位到错误界面。

怎么解决这两个坑呢?
先不着急,我们先来看看怎么发起get,post请求。

CloseableHttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet("http://www.baidu.com");
CloseableHttpResponse response = client.execute(get);

这样就对百度发起了一次http的get请求。
这个response里面包含了header,页面内容等。
然后怎么获取Header中的信息,和页面内容呢?

String[] cookies = response.getHeaders("Set-Cookie");
String html = Utils.getHtml(response.getEntity.getContent,"GB2312");

这样就可以获得cookie,和html页面内容,当然还有其他方法,稍微看一下API就知道具体有什么方法了,基本从名字就可以看出来时干什么用的了。
然后Utils.getHtml是我自己的一个静态方法,代码如下。

    public String getHtml(InputStream inputstream,String encoding)throws IOException{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];// 1K buffer
        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        is.close();
        return new String(bos.toByteArray(), encoding);
    }

接下来是Post请求。
post请求你总是要post点东西的嘛,所以先构造Body的。
所以代码如下

    HttpPost post = new HttpPost("http://www.baidu.com");
    //开始构造Body
    List<NameValuePair> postbody = new ArrayList<>();
    postbody.add(new BasicNameValuePair("__VIEWSTATE",viewState));
    postbody.add(new BasicNameValuePair("username",username));
    postbody.add(new BasicNameValuePair("password",password));
    postbody.addHeader("User-Agent",user-agent);
    //Body构造结束,开始处理编码格式
    UrlEncodedFormEntity GB_2312 = new UrlEncodedFormEntity(postbody,"GB2312");
    post.setEntity(GB_2312);
    //当然还可以给任何一个http使用代理,对我来说使用代理的好处是可以用burpsuite来看httphistory,查看自己发送的请求具体是什么。
    post.setConfig(RequestConfig.custom().setProxy(proxy).build());
    CloseableResponse postResponse = client.execute(postbody);

然后就拿到postResponse,用Jsoup解析。

    String html = Utils.getHtml(postResponse.getEntity().getContext(),"GB2312");
    Document document = Jsoup.parse(html);
    Elements elements = document.select("input[name=__VIEWSTATE]");

然后就把需要的内容爬下来了。

以上代码基本手写,没有借助IDE,如果有什么小错误根据IDE提示稍微修改一下就可以。

不是说要解决那两个坑的吗?

  • 稍微看仔细一点应该就知道,那两个坑已经解决了吧。
  • 就到这里吧,如果在看到这篇博客的时候有什么困惑,我的邮箱:solomonchn1@Gmail.com。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值