网络爬虫技术Jsoup——爬到一切你想要的

本文介绍了使用Jsoup爬虫技术从**点评网站抓取健身场馆数据的过程,包括新建项目、解析HTML、获取数据并展示在ListView上。详细讲解了Jsoup的功能以及爬虫的基本思路,提供了实战案例和遇到的问题,强调掌握Javascript的重要性。
摘要由CSDN通过智能技术生成

本文由我的微信公众号(bruce常)原创首发,
并同步发表到csdn博客,欢迎转载,2016年12月11日。

概述:

本周五,接到一个任务,要使用爬虫技术来获取某点评网站里面关于健身场馆的数据,之前从未接触过爬虫技术,于是就从网上搜了一点学习资料,本篇文章就记录爬虫技术Jsoup技术,爬虫技术听名称很牛叉,其实没什么难点,慢慢的用心学习就会了。

Jsoup介绍:

Jsoup 是一个 Java 的开源HTML解析器,可直接解析某个URL地址、HTML文本内容,Jsoup官网jar包下载地址

Jsoup主要有以下功能:
1. 从一个URL,文件或字符串中解析HTML
2. 使用DOM或CSS选择器来查找、取出数据
3. 对HTML元素、属性、文本进行操作
4. 清除不受信任的HTML (来防止XSS攻击)

使用Jsoup爬虫技术你需要的能力有:

  1. 我们是用安卓开发的,首先肯定要有一定的安卓开发能力,会写简单的页面。
  2. Jsoup中用到了Javascript语言,没有此语言能力在获取数据的时候就比较吃力,这是此爬虫技术的重中之重。
  3. 查阅文档与解决问题的能力和技巧(有点废话)

上面三条中对于一个安卓开发者来说,最难的就是熟练使用Javascript语言,小编就遇到了这个问题,小编还有一定的javascript基础,系统的学习过此语言,但是在使用中还是很吃力的,问同学、问朋友、问同事,最后还是靠自己来获取自己想要的数据。

爬虫技术没那么难,思路就是这么的简单

  1. 得到自己想要爬取数据的url.
  2. 通过Jsoup的jar包中的方法将Html解析成Document,
  3. 使用Document中的一些列get、first、children等方法获取自己想要的数据,如图片地址、名称、时间。
  4. 将得到的数据封装成自己的实体类。
  5. 将实体中的数据在页面加载出来。

实战,获取**点评网站中的场馆数据:

先奉上效果图,没有图不说话:

image

这就是今天要实现的效果,左边图片是场馆的logo,右边上方是场馆的名称,下边是场馆的地址信息,点击进去可以根据超链接地址跳转新的页面,页面的Url地址小编已经拿到,但可能是因为重定向的问题,webview没有加载出来,有兴趣的可以输入链接地址来验证。

首先:新建一个空的项目.

上面的效果,只要接触过安卓开发的都能写出来,所以不是本篇文章的重点,这里就不过多说明,大家可以使用ListView或者RecyclerView来实现,我这里用ListView。

小编这里是为了加入侧边栏所以使用的是DrawerLayout,但后来没有用到,所以也就没有侧边栏的效果,不过后期如有时间会加上去的,上一页下一页是为了简单的模仿浏览器中的操作,此效果只能显示前9页数据,网页链接中有50页的数据,为什么没有实现呢?

很简单,因为50页的链接地址不是一次性返回的,小编为了方便,只获取了前9页数据的url,毕竟是为了抓取数据显示而已。

其次:主程序设计
  1. 通过网页得到**点评健身场馆的url地址是:http://www.dianping.com/search/category/2/45
  2. 抓取数据是一个耗时的操作,需要在一个线程中完成,这里使用 new Thread(runnable).start()方式,在runnable代码中获取场馆的logo、名称、地址如下:
Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Connection conn = Jsoup.connect(url);
            // 修改http包中的header,伪装成浏览器进行抓取
            conn.header("User-Agent", userAgent);
            Document doc = null;
            try {
                doc = conn.get();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //获取场馆的数据
            Element elementDiv = doc.getElementById("shop-all-list");
            Elements elementsUl = elementDiv.getElementsByTag("ul");
            Elements elements = elementsUl.first().getElementsByTag("li");
            for (Element element : elements) {
                Elements elements1 = element.children();
                String targetUrl = elements1.get(0).getElementsByTag("a").attr("href");

                String img = elements1.get(0).getElementsByTag("img").first().attr("data-src");
                if (img.contains(".jpg")) {
                    int a = img.indexOf(".jpg");
                    img = img.substring(0, a + 4);
                }

                String radiumName = elements1.get(1).child(0).getElementsByTag("h4").text();
                String address0 = elements1.get(
Jsoup+httpclient 模拟登陆和抓取页面 package com.app.html; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.cookie.CookieSpec; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpMethodParams; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import com.app.comom.FileUtil; public class HttpClientHtml { private static final String SITE = "login.goodjobs.cn"; private static final int PORT = 80; private static final String loginAction = "/index.php/action/UserLogin"; private static final String forwardURL = "http://user.goodjobs.cn/dispatcher.php/module/Personal/?skip_fill=1"; private static final String toUrl = "d:\\test\\"; private static final String css = "http://user.goodjobs.cn/personal.css"; private static final String Img = "http://user.goodjobs.cn/images"; private static final String _JS = "http://user.goodjobs.cn/scripts/fValidate/fValidate.one.js"; /** * 模拟等录 * @param LOGON_SITE * @param LOGON_PORT * @param login_Action * @param params * @throws Exception */ private static HttpClient loginHtml(String LOGON_SITE, int LOGON_PORT,String login_Action,String ...params) throws Exception { HttpClient client = new HttpClient(); client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT); // 模拟登录页面 PostMethod post = new PostMethod(login_Action); NameValuePair userName = new NameValuePair("memberName",params[0] ); NameValuePair password = new NameValuePair("password",params[1] ); post.setRequestBody(new NameValuePair[] { userName, password }); client.executeMethod(post); post.releaseConnection(); // 查看cookie信息 CookieSpec cookiespec = CookiePolicy.getDefaultSpec(); Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies()); if (cookies != null) if (cookies.length == 0) { System.out.println("Cookies is not Exists "); } else { for (int i = 0; i < cookies.length; i++) { System.out.println(cookies[i].toString()); } } return client; } /** * 模拟等录 后获取所需要的页面 * @param client * @param newUrl * @throws Exception */ private static String createHtml(HttpClient client, String newUrl) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); String filePath = toUrl + format.format(new Date() )+ "_" + 1 + ".html"; PostMethod post = new PostMethod(newUrl); client.executeMethod(post); //设置编码 post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "GBK"); String content= post.getResponseBodyAsString(); FileUtil.write(content, filePath); System.out.println("\n写入文件成功!"); post.releaseConnection(); return filePath; } /** * 解析html代码 * @param filePath * @param random * @return */ private static String JsoupFile(String filePath, int random) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); File infile = new File(filePath); String url = toUrl + format.format(new Date()) + "_new_" + random+ ".html"; try { File outFile = new File(url); Document doc = Jsoup.parse(infile, "GBK"); String html="<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"; StringBuffer sb = new StringBuffer(); sb.append(html).append("\n"); sb.append("<html>").append("\n"); sb.append("<head>").append("\n"); sb.append("<title>欢迎使用新安人才网个人专区</title>").append("\n"); Elements meta = doc.getElementsByTag("meta"); sb.append(meta.toString()).append("\n"); ////////////////////////////body////////////////////////// Elements body = doc.getElementsByTag("body"); ////////////////////////////link////////////////////////// Elements links = doc.select("link");//对link标签有href的路径都作处理 for (Element link : links) { String hrefAttr = link.attr("href"); if (hrefAttr.contains("/personal.css")) { hrefAttr = hrefAttr.replace("/personal.css",css); Element hrefVal=link.attr("href", hrefAttr);//修改href的属性值 sb.append(hrefVal.toString()).append("\n"); } } ////////////////////////////script////////////////////////// Elements scripts = doc.select("script");//对script标签 for (Element js : scripts) { String jsrc = js.attr("src"); if (jsrc.contains("/fValidate.one.js")) { String oldJS="/scripts/fValidate/fValidate.one.js";//之前的css jsrc = jsrc.replace(oldJS,_JS); Element val=js.attr("src", jsrc);//修改href的属性值 sb.append(val.toString()).append("\n").append("</head>"); } } ////////////////////////////script////////////////////////// Elements tags = body.select("*");//对所有标签有src的路径都作处理 for (Element tag : tags) { String src = tag.attr("src"); if (src.contains("/images")) { src = src.replace("/images",Img); tag.attr("src", src);//修改src的属性值 } } sb.append(body.toString()); sb.append("</html>"); BufferedReader in = new BufferedReader(new FileReader(infile)); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(outFile), "gbk")); String content = sb.toString(); out.write(content); in.close(); System.out.println("页面已经爬完"); out.close(); } catch (IOException e) { e.printStackTrace(); } return url; } public static void main(String[] args) throws Exception { String [] params={"admin","admin123"}; HttpClient client = loginHtml(SITE, PORT, loginAction,params); // 访问所需的页面 String path=createHtml(client, forwardURL); System.out.println( JsoupFile(path,1)); } }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值