2019-08-20 11:05:04 weixin_38745233 阅读数 2568
  • Python网络爬虫基础篇

    本课程主要给大家分享基于Python语言的网络爬虫基础篇体验,其中讲解爬虫原理介绍,urllib和requests爬虫库的使用,以及网络爬虫中的数据分析与信息提取。通过模拟Web的GET和POST请求来爬取数据,介绍如何应对各种常见反爬机制。后续还会有更深入的网络爬虫介绍体验,请大家持续关注。

    8303 人正在学习 去看看 CSDN讲师

Python爬虫太火了,没写过爬虫,都不敢说自己学过Python?!

想要做爬虫,就得先学会数据分析,使用爬虫框架,其中,Scrapy是一个经典的爬虫框架,Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

笔者就打算使用Scrapy框架来爬取网站数据,But!第一步就卡住了,Scrapy如何下载安装?
笔者在网上发现一个讲ScrapyScrapy下载和安装及创建项目的小视频,我觉得讲的超基础,很适合小白,特来分享给大家~

如果你也在学习python做爬虫,跟我一起看看下方视频,听知名技术专家李刚老师对Python Scrapy的下载和安装的详细解答,

Python 爬虫

李刚老师出版的《疯狂Java》系列图书曾得到市场的广泛认可,经过多次再版,已被多家高校选作教材。上方视频来自于李刚老师的在线视频课程《21天通关Python》第十章Python爬虫

鉴于大家都有学习Python的困惑,今天就给大家推荐一本巨有影响力的Python实战书,上线时间仅2个月,就超越了众多实力派,成京东和当当网上的长期畅销图书,并且收获了3.4W的五星好评。

这本书可谓是笔者独家私藏图书之一了,对我学习Python有着莫大的帮助,在京东上也常常"断货",这次拿出来给大家分享一下,希望能帮到大家。

《21天通关Python》视频课程以畅销图书为教材,由图书作者李刚亲自操刀讲解;上手门槛低,可作为0基础掌握Python教材;书籍+线上复合型学习场景特别适合Python小白学习!

点击查看课程:
https://edu.csdn.net/bundled/detail/49?utm_source=jiansuopy67_1
(含图书邮寄+视频教程+社群答疑+导师带队)

笔者跟大家分享一个福利!下单时输入优惠码csdn66,立减20元,券后仅需99元!

扫码入Python技术交流群,可免费听技术讲座+领学习资料+视频课免费看!
在这里插入图片描述

2019-02-13 18:23:20 qq_43667184 阅读数 70
  • Python网络爬虫基础篇

    本课程主要给大家分享基于Python语言的网络爬虫基础篇体验,其中讲解爬虫原理介绍,urllib和requests爬虫库的使用,以及网络爬虫中的数据分析与信息提取。通过模拟Web的GET和POST请求来爬取数据,介绍如何应对各种常见反爬机制。后续还会有更深入的网络爬虫介绍体验,请大家持续关注。

    8303 人正在学习 去看看 CSDN讲师
               

    刚开始接触网络爬虫,怎一个“菜”字了得!经过几次的折磨,对其原理以及其中用到的json技术有了大致的了解,故作一总结,供有同样迷惑的朋友参考学习。

    自己爬取的网站内容为12306的余票查询模块。利用火狐浏览器为Web开发者置的Web控制台,可得到爬取网页的请求网址,如下图所示:


其中的请求网址即为我们需要爬取的网址。另外,可得知其请求协议采用的是Https协议,采用GET方式访问。爬取源代码如下所示:
        public static String queryDate = "2015-04-19"public static String from_station = "JNK"public static String to_station = "BJP"public static void main(String[] args) throws Exception {  HostnameVerifier hv = new HostnameVerifier() {   public boolean verify(String urlHostName, SSLSession session) {    System.out.println("Warning: URL Host: " + urlHostName      + " vs. " + session.getPeerHost());    return true;   }  };        String url = "https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate="    + queryDate    + "&from_station="    + from_station    + "&to_station="    + to_station;  ProtocolUrlValidator.trustAllHttpsCertificates();  HttpsURLConnection.setDefaultHostnameVerifier(hv);  String result = WebServiceUtil.invokeByHTTPGET(url, null);    Gson gson = new Gson();  Trains trains = gson.fromJson(result, Trains.class);    List<Item> items = trains.getData().getItems();    if (trains.getHttpstatus() != 200) {   trains.getMessages();  } else {   if (items != null && items.size() != 0)    for (Item item : items) {     System.out.println(item);    }  } }}
<span style="font-size:14px;">由于使用的协议为Https,故访问之前需要先进行证书的校验。其中蓝色代码块为我们需要访问的网址,涉及到的invokeByHTTPGET(url,null)代码如下所示:</span>
<span style="font-size:18px;">public class WebServiceUtil /**  * 通过SOAP1.1协议调用Web服务  *   * @param wsdl  WSDL路径  * @param method 方法名  * @param namespace 命名空间  * @param headerParameters 头参数  * @param bodyParameters   体参数  * @param isBodyParametersNS 体参数是否有命名空间  * @return String  * @throws Exception  */ public static String invokeBySoap11(String wsdl, String method,   String namespace, Map<String, String> headerParameters,   Map<String, String> bodyParameters, boolean isBodyParametersNS)   throws Exception {  StringBuffer soapOfResult = null;  // 去除 ?wsdl,获取方法列表  int length = wsdl.length();  wsdl = wsdl.substring(0, length - 5);  URL url = new URL(wsdl);  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  conn.setRequestMethod("POST");  conn.setDoInput(true);  conn.setDoOutput(true);  conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");  OutputStream out = conn.getOutputStream();  // 获取soap1.1版本消息  StringBuilder sb = new StringBuilder();  sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"                 xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ");  sb.append("xmlns:ns0=\"" + namespace + "\"");  sb.append(">");  if (headerParameters != null) {   sb.append("<soap:Header>");   for (Entry<String, String> headerParameter : headerParameters     .entrySet()) {    sb.append("<ns0:");    sb.append(headerParameter.getKey());    sb.append(">");    sb.append(headerParameter.getValue());    sb.append("</ns0:");    sb.append(headerParameter.getKey());    sb.append(">");   }   sb.append("</soap:Header>");  }  sb.append("<soap:Body><ns0:");  sb.append(method);  sb.append(">");  // 输入参数  if (bodyParameters != null) {   for (Entry<String, String> inputParameter : bodyParameters     .entrySet()) {    if (isBodyParametersNS) {     sb.append("<ns0:");     sb.append(inputParameter.getKey());     sb.append(">");     sb.append(inputParameter.getValue());     sb.append("</ns0:");     sb.append(inputParameter.getKey());     sb.append(">");    } else {     sb.append("<");     sb.append(inputParameter.getKey());     sb.append(">");     sb.append(inputParameter.getValue());     sb.append("</");     sb.append(inputParameter.getKey());     sb.append(">");    }   }  }  sb.append("</ns0:");  sb.append(method);  sb.append("></soap:Body></soap:Envelope>");  //System.out.println(sb.toString());  out.write(sb.toString().getBytes());  int code = conn.getResponseCode();  if (code == 200) {   InputStream is = conn.getInputStream();   byte[] b = new byte[1024];   int len = 0;   soapOfResult = new StringBuffer();   while ((len = is.read(b)) != -1) {    String s = new String(b, 0, len, "UTF-8");    soapOfResult.append(s);   }  }  conn.disconnect();  return soapOfResult == null ? null : soapOfResult.toString(); } /**  * 通过SOAP1.2协议调用Web服务  *   * @param wsdl  * @param method  * @param namespace  * @param headerParameters  * @param bodyParameters  * @param isBodyParametersNS  * @return  * @throws Exception  */ public static String invokeBySoap12(String wsdl, String method,   String namespace, Map<String, String> headerParameters,   Map<String, String> bodyParameters, boolean isBodyParametersNS)   throws Exception {  StringBuffer soapOfResult = null;  // 去除 ?wsdl  int length = wsdl.length();  wsdl = wsdl.substring(0, length - 5);  URL url = new URL(wsdl);  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  conn.setRequestMethod("POST");  conn.setDoInput(true);  conn.setDoOutput(true);  conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");  OutputStream out = conn.getOutputStream();  // 获取soap1.1版本消息  StringBuilder sb = new StringBuilder();  sb.append("<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"                 xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");  sb.append("xmlns:ns0=\"" + namespace + "\"");  sb.append(">");  if (headerParameters != null) {   sb.append("<soap12:Header>");   for (Entry<String, String> headerParameter : headerParameters     .entrySet()) {    sb.append("<ns0:");    sb.append(headerParameter.getKey());    sb.append(">");    sb.append(headerParameter.getValue());    sb.append("</ns0:");    sb.append(headerParameter.getKey());    sb.append(">");   }   sb.append("</soap12:Header>");  }  sb.append("<soap12:Body><ns0:");  sb.append(method);  sb.append(">");  // 输入参数  if (bodyParameters != null) {   for (Entry<String, String> inputParameter : bodyParameters     .entrySet()) {    if (isBodyParametersNS) {     sb.append("<ns0:");     sb.append(inputParameter.getKey());     sb.append(">");     sb.append(inputParameter.getValue());     sb.append("</ns0:");     sb.append(inputParameter.getKey());     sb.append(">");    } else {     sb.append("<");     sb.append(inputParameter.getKey());     sb.append(">");     sb.append(inputParameter.getValue());     sb.append("</");     sb.append(inputParameter.getKey());     sb.append(">");    }   }  }  sb.append("</ns0:");  sb.append(method);  sb.append("></soap12:Body></soap12:Envelope>");  System.out.println(sb.toString());  out.write(sb.toString().getBytes());  int code = conn.getResponseCode();  if (code == 200) {   InputStream is = conn.getInputStream();   byte[] b = new byte[1024];   int len = 0;   soapOfResult = new StringBuffer();   while ((len = is.read(b)) != -1) {    String s = new String(b, 0, len, "UTF-8");    soapOfResult.append(s);   }  }  conn.disconnect();  return soapOfResult == null ? null : soapOfResult.toString(); } /**  * 通过HTTP POST传参方式调用服务  *   * @param urlPath  * @param method  * @param namespace  * @param inputParameters  * @return  * @throws Exception  */ public static String invokeByHTTPPOST(String urlPath, Map<String, String> inputParameters)   throws Exception {  StringBuffer resultStr = null;  URL url = new URL(urlPath);  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  conn.setRequestMethod("POST");  conn.setDoInput(true);  conn.setDoOutput(true);  conn.setRequestProperty("Content-Type",    "application/x-www-form-urlencoded");  StringBuilder sb = new StringBuilder();  // 输入参数  if (inputParameters != null) {   for (Entry<String, String> inputParameter : inputParameters     .entrySet()) {    sb.append(inputParameter.getKey());    sb.append("=");    sb.append(inputParameter.getValue());    sb.append("&");   }   sb.deleteCharAt(sb.length() - 1);  }  System.out.println(sb.toString());  OutputStream out = conn.getOutputStream();  out.write(sb.toString().getBytes());  int code = conn.getResponseCode();  if (code == 200) {   InputStream is = conn.getInputStream();   byte[] b = new byte[1024];   int len = 0;   resultStr = new StringBuffer();   while ((len = is.read(b)) != -1) {    String s = new String(b, 0, len, "UTF-8");    resultStr.append(s);   }  }  conn.disconnect();  return resultStr == null ? null : resultStr.toString(); } /**  * 通过HTTP GET传参方式调用服务  *   * @param urlPath   url路径  * @param method 方法名  * @param namespace 命名空间  * @param inputParameters 输入参数  * @return String  * @throws Exception  */ public static String invokeByHTTPGET(String urlPath,  Map<String, String> inputParameters)   throws Exception {  StringBuilder sb = new StringBuilder();  sb.append(urlPath);  // GET参数  if (inputParameters != null) {   sb.append("?");   //entrySet()方法 返回此映射中包含的映射关系的 set 视图集合   //Map.Entry表示单个映射关系即一个key+value   for (Entry<String, String> inputParameter : inputParameters     .entrySet()) {    sb.append(inputParameter.getKey());    sb.append("=");    sb.append(inputParameter.getValue());    sb.append("&");   }   //作用:去除最后一个拼接的'&'字符   sb.deleteCharAt(sb.length() - 1);  }  System.out.println(sb.toString());  URL url = new URL(sb.toString());  HttpURLConnection conn = (HttpURLConnection) url.openConnection();  conn.setRequestMethod("GET");  conn.setDoOutput(true);  int code = conn.getResponseCode();  StringBuffer resultString = null;  if (code == 200) {   InputStream is = conn.getInputStream();   byte[] b = new byte[4096];   int len = 0;   resultString = new StringBuffer();   while ((len = is.read(b)) != -1) {    String s = new String(b, 0, len, "UTF-8");    //System.out.println(len+">>>>"+s);    resultString.append(s);   }  }  conn.disconnect();  return resultString == null ? null : resultString.toString(); }</span>

以上代码块涉及到的发送请求方式有通过SOAP1.1协议调用Web服务、通过SOAP1.2协议调用Web服务、

通过HTTP POST传参方式调用服务和通过HTTP GET传参方式调用服务。其具体的请求方式在源代码中以注释方式以详细给出,故此处不再赘述。

在爬取过程中,我们还需要用到json在线校验工具,网址为:点击打开链接。主要利用此工具完成的操作为:验证json格式的正确性,根据json串生成相应的POJO类。如下图所示:

                                                                                                                                           json格式校验

                                                                                                                                                                                                      生成POJO类
<span style="font-size:18px;">至此,网络爬虫的过程基本结束。此次实验的返回结果如下图所示:</span>

注:自己对GSon解析json还存在一定的误区。对于json串中的Key,其实是与相应类中的变量名一一对应的,否则,在解析式将会是null!例如,

以上的json串中存在key为data,则在创建POJO时,不可随意更变变量名,若将private List<Item> datas;改写为private List<Item> items;则会使变List<Item> items = trains.getData().getItems();返回null。若自己需要更改变量名的话,可以采用注解的方式解决,例如@SerializedName("datas")private List<Item> items;

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

2017-02-12 23:06:56 qq_30379689 阅读数 16939
  • Python网络爬虫基础篇

    本课程主要给大家分享基于Python语言的网络爬虫基础篇体验,其中讲解爬虫原理介绍,urllib和requests爬虫库的使用,以及网络爬虫中的数据分析与信息提取。通过模拟Web的GET和POST请求来爬取数据,介绍如何应对各种常见反爬机制。后续还会有更深入的网络爬虫介绍体验,请大家持续关注。

    8303 人正在学习 去看看 CSDN讲师

Android实战——jsoup实现网络爬虫,爬糗事百科主界面


本篇文章包括以下内容:

前言

对于Android初学者想要做项目时,最大的烦恼是什么?毫无疑问是数据源的缺乏,当然可以选择第三方接口提供数据,也可以使用网络爬虫获取数据,这样就不用第三方数据作为支持。本来是打算爬一些购物网站的数据,由于他们的反爬做得好,所以没办法爬到数据,只能爬取糗事百科的数据,或许聪明的你会想到可以高仿个糗事百科作为自己的练手项目,利用jsoup是完全没问题的

jsoup的学习需要结合前端的基础知识,爬取前端的数据,如果你学过JS,那么你可以自己完全不用看文档的情况下,使用该框架,因为其设计与JS的使用几乎相同,废话不多说,开车啦

jsoup的简介

使用项目原话:jsoup是一个Java库来处理实际的HTML。它提供了一个非常方便的API来提取和操纵数据,使用最好的DOM,CSS和jquery-like方法

项目地址:https://github.com/jhy/jsoup
中文文档:http://www.open-open.com/jsoup/

jsoup的配置

jsoup的配置很简单,需要在gradle中添加以下依赖

compile 'org.jsoup:jsoup:1.10.2'

由于jsoup需要获取网络数据,所以记得添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

jsoup的使用

一、获取HTML

jsoup提供两种网络请求,get和post,使用代码也及其简单,我们首先爬取糗事百科首页的HTML。注意:由于是网络请求操作,必须放在子线程中运行,否则4.4以上的版本会报错

① get方式

new Thread() {
    @Override
    public void run() {
        super.run();
        try {
            Document doc = Jsoup.connect("http://www.qiushibaike.com/8hr/page/1/").get();
            Log.e("一、HTML內容", doc.toString());
            }
        catch{
        }
    }
}.start();

② post方式

Document doc = Jsoup.connect("http://www.qiushibaike.com/8hr/page/1/")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  .timeout(3000)
  .post();

这里对post的参数介绍一下

  • connect:设置连接的Url
  • data:设置post的键值对数据
  • userAgent:设置用户代理(请求头的东西,可以判断你是PC还是Mobile端)
  • cookie:设置缓存
  • timeout:设置请求超时
  • post:发送post请求

既然已经获取HTML的Document对象了,接下来就是分析Html元素的时候了

二、获取Html元素

① 网页端

以糗事百科为例子,我们查看糗事百科首页的数据对应的Html元素是什么,我们可以通过F12,找到对应的Html元素

可以看到一个a标签就是文章详情的内容,我们可以通过这个a标签的class=”contentHerf”作为唯一标识来获取该链接,获取之后,继续爬取详情页的文章详细内容,所以我们通过爬取的a标签的链接进入该文章的详情页

当然也有一些详情页有图片的,我们可以通过图片的的class=”thumb”作为唯一标识来爬取图片里面的链接

由于糗事百科采用分页加载的情况,我们需要在爬取完第一张内容后,接着爬取第二章的内容,下面是糗事百科的分页Url的规则,很简单,我们可以通过一个循环就可以了

http://www.qiushibaike.com/8hr/page/1/
http://www.qiushibaike.com/8hr/page/2/
http://www.qiushibaike.com/8hr/page/3/
http://www.qiushibaike.com/8hr/page/4/
http://www.qiushibaike.com/8hr/page/5/

好了,分析完网页端之后,就应该在我们的Android端采用代码,将上面的步骤实现出来了

② Android端

通过上面的分析后,可以总结我们需要实现的步骤有:

  1. 爬取主页的详情页url
  2. 进入详情页爬取内容和图片
  3. 循环爬取第二页、第三页…

聪明的你,可能会想到第四步第五步…

  1. 封装Bean对象
  2. 使用ListView填充内容
  3. 爬取日期、作者、评论等内容完善项目

1) 爬取主页的详情页url

爬取主页的url可以通过a标签的class=”contentHerf”,我们通过jsoup的属性选择器来实现,这里会用到css知识,jsoup中文文档也有很详细的介绍

Document doc = Jsoup.connect("http://www.qiushibaike.com/8hr/page/1/").get();
Elements els = doc.select("a.contentHerf");
Log.e("一、HTML內容", els.toString());

for (int i = 0; i < els.size(); i++) {
    Element el = els.get(i);
    Log.e("1.标题", el.text());

    String href = el.attr("href");
    Log.e("2.链接", href);
}

这里对使用到的对象进行介绍

  • Document:相当于一个Html文件
  • Elements:相当于一个标签的集合
  • Element:相当于一个标签

这里要注意Elements与Element的toString()方法和text()方法

  • toString():打印出来的是标签的Html内容
  • text():打印出来的是标签对应的文本内容

css选择器

  • select():获取符合属性选择器要求的标签内容
  • 或getElementById:获取符合ID选择器要求的标签内容
  • 或getElementsByTag:获取符合Tag选择器要求的标签内容

2) 进入详情页爬取内容和图片

这段代码也相当简单,这里就不多解释了

Document doc = Jsoup.connect("http://www.qiushibaike.com/8hr/page/1/").get();
Elements els = doc.select("a.contentHerf");
Log.e("一、HTML內容", els.toString());

for (int i = 0; i < els.size(); i++) {
    Element el = els.get(i);
    Log.e("1.标题", el.text());

    String href = el.attr("href");
    Log.e("2.链接", href);

    //获取详情页内容
    Document doc_detail = Jsoup.connect("http://www.qiushibaike.com" + href).get();
    Elements els_detail = doc_detail.select(".content");
    Log.e("3.內容", els_detail.text());

    //获取图片
    Elements els_pic = doc_detail.select(".thumb img[src$=jpg]");
    if (!els_pic.isEmpty()) {
        String pic = els_pic.attr("src");
        Log.e("4.图片连接", "" + pic);
    } else {
        Log.e("4.图片连接", "无");
    }
}

3) 循环爬取第二页、第三页…

这里只需要嵌套一个循环进去就可以了,完整代码如下

public class JsoupActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jsoup);

        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    for (int k = 0; k < 5; k++) {
                        Document doc = Jsoup.connect("http://www.qiushibaike.com/8hr/page/" + k + "/").get();
                        Elements els = doc.select("a.contentHerf");
                        Log.e("一、HTML內容", els.toString());

                        for (int i = 0; i < els.size(); i++) {
                            Element el = els.get(i);
                            Log.e("1.标题", el.text());

                            String href = el.attr("href");
                            Log.e("2.链接", href);

                            Document doc_detail = Jsoup.connect("http://www.qiushibaike.com" + href).get();
                            Elements els_detail = doc_detail.select(".content");
                            Log.e("3.內容", els_detail.text());

                            Elements els_pic = doc_detail.select(".thumb img[src$=jpg]");
                            if (!els_pic.isEmpty()) {
                                String pic = els_pic.attr("src");
                                Log.e("4.图片连接", "" + pic);
                            } else {
                                Log.e("4.图片连接", "无");
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }
}

4) 当然,我们爬取到的内容之后,毫无疑问就是要封装成对象,通过ArrayList存储起来,这样你的数据源就解决了

public class Xiaohua { 
    private String content;
    private String title;
    private String url;
    private String userName;
    private String date;
}

5) 后面爬取作者、日期、评论等信息就由你们去练习了,然后界面一仿,项目就出来了

三、爬取结果

02-12 08:16:55.010 18074-18110/com.handsome.boke2 E/1.标题: 小时候有个常去楼主家的阿姨总是把楼主叫成楼主哥哥的名字,终于有一天,楼主忍无可忍,大骂了她一顿:“你这个人是不是白痴啊?”她暴怒了,立马告诉了楼主的爸爸,楼主永远也忘不了哥哥被揍时眼睛里的无辜与绝望...
02-12 08:16:55.011 18074-18110/com.handsome.boke2 E/2.链接: /article/118543240
02-12 08:16:55.329 18074-18110/com.handsome.boke2 E/3.內容: 小时候有个常去楼主家的阿姨总是把楼主叫成楼主哥哥的名字,终于有一天,楼主忍无可忍,大骂了她一顿:“你这个人是不是白痴啊?”她暴怒了,立马告诉了楼主的爸爸,楼主永远也忘不了哥哥被揍时眼睛里的无辜与绝望...
02-12 08:16:55.331 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:55.881 18074-18110/com.handsome.boke2 E/1.标题: 一朋友,给暗恋许久的女神,匿名网购了一大堆的礼物,可把女神高兴的,在朋友圈发说说,这是谁买的。告诉我,我要做他女朋友! 朋友乐坏了,于是激动的说,是我,是我! 那女神愣了愣,然后把礼物全部退给了他……
02-12 08:16:55.881 18074-18110/com.handsome.boke2 E/2.链接: /article/118542673
02-12 08:16:56.104 18074-18110/com.handsome.boke2 E/3.內容: 一朋友,给暗恋许久的女神,匿名网购了一大堆的礼物,可把女神高兴的,在朋友圈发说说,这是谁买的。告诉我,我要做他女朋友! 朋友乐坏了,于是激动的说,是我,是我! 那女神愣了愣,然后把礼物全部退给了他……
02-12 08:16:56.106 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:56.106 18074-18110/com.handsome.boke2 E/1.标题: LZ在非洲曾经遇到过抢劫,有人拿枪指着我们,愣了一下热血当头没当回事,继续反抗,后来情急之下,他射了一枪,结果发现那是玩具枪,特么的,我们抓起扫把就把那个劫匪揍了一顿。事后想想,又害怕又想笑。
02-12 08:16:56.106 18074-18110/com.handsome.boke2 E/2.链接: /article/118542683
02-12 08:16:56.608 18074-18110/com.handsome.boke2 E/3.內容: LZ在非洲曾经遇到过抢劫,有人拿枪指着我们,愣了一下热血当头没当回事,继续反抗,后来情急之下,他射了一枪,结果发现那是玩具枪,特么的,我们抓起扫把就把那个劫匪揍了一顿。事后想想,又害怕又想笑。
02-12 08:16:56.609 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:56.609 18074-18110/com.handsome.boke2 E/1.标题: 今年换了工作,今天第一天上班,老妈早早起床准备早餐,等我吃完早餐准备出门的时候,老妈塞给我一个红包说,新年第一天上班图吉利。当时急着上班也没有细看就放在口袋里。等上班空闲的时候,掏出红包,发现红包里只有一张纸条,上面写着四个大字:好好工作……
02-12 08:16:56.609 18074-18110/com.handsome.boke2 E/2.链接: /article/118542647
02-12 08:16:57.140 18074-18110/com.handsome.boke2 E/3.內容: 今年换了工作,今天第一天上班,老妈早早起床准备早餐,等我吃完早餐准备出门的时候,老妈塞给我一个红包说,新年第一天上班图吉利。当时急着上班也没有细看就放在口袋里。等上班空闲的时候,掏出红包,发现红包里只有一张纸条,上面写着四个大字:好好工作……
02-12 08:16:57.142 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:57.142 18074-18110/com.handsome.boke2 E/1.标题: 腰疼,趴在床上,让大侄子来给我踩踩后背,踩得我挺舒服,没忍住,放个响屁,小家伙愣了一下,然后狠狠 踹 我 屁 股“让你蹦我!让你蹦我!”。。。。
02-12 08:16:57.142 18074-18110/com.handsome.boke2 E/2.链接: /article/118542708
02-12 08:16:57.379 18074-18110/com.handsome.boke2 E/3.內容: 腰疼,趴在床上,让大侄子来给我踩踩后背,踩得我挺舒服,没忍住,放个响屁,小家伙愣了一下,然后狠狠 踹 我 屁 股“让你蹦我!让你蹦我!”。。。。
02-12 08:16:57.382 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:57.382 18074-18110/com.handsome.boke2 E/1.标题: 闺蜜的妈妈非常迷信,自从闺蜜放假回家陪妈妈去了几次麻将馆后,她妈每次都能赢钱,所以她妈这一个寒假只要去打麻将,都要拉着她去,直到昨天闺蜜开学,她妈妈送她走得时候,眼泪汪汪的对闺蜜说:宝贝,这是我第一次不舍的你走~
02-12 08:16:57.382 18074-18110/com.handsome.boke2 E/2.链接: /article/118542657
02-12 08:16:57.881 18074-18110/com.handsome.boke2 E/3.內容: 闺蜜的妈妈非常迷信,自从闺蜜放假回家陪妈妈去了几次麻将馆后,她妈每次都能赢钱,所以她妈这一个寒假只要去打麻将,都要拉着她去,直到昨天闺蜜开学,她妈妈送她走得时候,眼泪汪汪的对闺蜜说:宝贝,这是我第一次不舍的你走~
02-12 08:16:57.882 18074-18110/com.handsome.boke2 E/4.图片连接: 无
02-12 08:16:57.882 18074-18110/com.handsome.boke2 E/1.标题: 早上起床后发现阳台的地上到处是泡沫水,花盆里也有很多泡沫,而且地上躺着洗衣液的空瓶子,一下便明白了,转头去问熊孩子,熊孩子若无其事的说我只是给花洗洗头而已嘛!
02-12 08:16:57.882 18074-18110/com.handsome.boke2 E/2.链接: /article/118542709
02-12 08:16:58.391 18074-18110/com.handsome.boke2 E/3.內容: 早上起床后发现阳台的地上到处是泡沫水,花盆里也有很多泡沫,而且地上躺着洗衣液的空瓶子,一下便明白了,转头去问熊孩子,熊孩子若无其事的说我只是给花洗洗头而已嘛!
02-12 08:16:58.393 18074-18110/com.handsome.boke2 E/4.图片连接: 无

结语

网络爬虫虽然带来了很多数据源的问题,但很多网站都已经通过一些技术实现反爬虫的效果了,所以大家还是以学习jsoup为主,不管是Android端还是Web端jsoup的用处很广泛,所以掌握起来是必须的,听说豆瓣和知乎都可以爬出来哦,想做项目的同学可以去试试哦

代码下载

2019-05-31 20:14:48 qq_39388534 阅读数 144
  • Python网络爬虫基础篇

    本课程主要给大家分享基于Python语言的网络爬虫基础篇体验,其中讲解爬虫原理介绍,urllib和requests爬虫库的使用,以及网络爬虫中的数据分析与信息提取。通过模拟Web的GET和POST请求来爬取数据,介绍如何应对各种常见反爬机制。后续还会有更深入的网络爬虫介绍体验,请大家持续关注。

    8303 人正在学习 去看看 CSDN讲师

一、浅谈网络爬虫

​随着网络的迅速发展,互联网成为大量信息的载体,如何有效的利用这些信息成为巨大的挑战。区别于搜索引擎,定向抓取相关网页资源的网络爬虫应用而生,可以根据既定的抓取目标有效的选择网络上需要的网页资源和信息。如用户想获得知乎豆瓣等网站上的主要数据进行分析,如用户想获得某个论坛贴吧内的所有图片等,把这项工作交给网络爬虫,可以大大提高人们的效率。

二、Jsoup简介

Jsoup是一个 Java 的开源HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常方便的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

Jsoup主要有以下功能:

  • 从一个字符串、文件或者一个 URL 中解析HTML
  • 提供一系列方法对HTML进行数据抽取
  • 对HTML元素、属性、文本进行操作
  • 消除不受信任的HTML (来防止XSS攻击)

简言之,安卓跟web爬虫基本上没什么区别,都是通过请求获得响应。Android返回的是json格式的字符串,web返回的是页面,通过Jsoup我们可以方便的对网页的数据进行操作。

三、Jsoup的配置

首先在Jsoup官网 https://jsoup.org/download 下载对应的jar包
在这里插入图片描述
并将下载的jar包导入项目的依赖库中

implementation ‘org.jsoup:jsoup:1.12.1’

然后在gradle中添加以下依赖

compile 'org.jsoup:jsoup:1.12.1'

由于jsoup需要获取网络数据,所以需要添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

四、Jsoup的使用

1.从一个字符串、文件或者一个 URL 中解析HTML

String html = "<html><head><title>First parse</title></head>"
  + "<body><p>Parsed HTML into a doc.</p></body></html>";
Document doc = Jsoup.parse(html);

当对象是URL时,使用 Jsoup.connect(String url)方法:

Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();

当URL请求为post方式而不是get方式时

Document doc = Jsoup.connect("http://example.com")
  .data("query", "Java")
  .userAgent("Mozilla")
  .cookie("auth", "token")
  .timeout(3000)
  .post();

2.提供一系列方法对HTML进行数据抽取
Jsoup将HTML解析成Document后,可以使用一系列DOM方法:

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");

Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
  String linkHref = link.attr("href");
  String linkText = link.text();
}

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:

查找元素

getElementById(String id)
getElementsByTag(String tag)
getElementsByClass(String className)
getElementsByAttribute(String key) (and related methods)
Element siblings: siblingElements(), firstElementSibling(), lastElementSibling(); nextElementSibling(), previousElementSibling()
Graph: parent(), children(), child(int index)

操作HTML和文本

append(String html), prepend(String html)
appendText(String text), prependText(String text)
appendElement(String tagName), prependElement(String tagName)
html(String value)

3.对HTML元素、属性、文本进行操作

在你解析一个Document之后可能想修改其中的某些属性值,然后再保存到磁盘或都输出到前台页面。
可以利用Jsoup进行如下操作:

Element div = doc.select("div").first(); // <div></div>
div.html("<p>lorem ipsum</p>"); // <div><p>lorem ipsum</p></div>
div.prepend("<p>First</p>");//在div前添加html内容
div.append("<p>Last</p>");//在div之后添加html内容
// 添完后的结果: <div><p>First</p><p>lorem ipsum</p><p>Last</p></div>

Element span = doc.select("span").first(); // <span>One</span>
span.wrap("<li><a href='http://example.com/'></a></li>");
// 添完后的结果: <li><a href="http://example.com"><span>One</span></a></li>

这是对一个HTML中内容元素的设置
关于Jsoup的更多使用细节可以参考中文文档:https://www.open-open.com/jsoup/

五、爬取数据的思路

1.根据想要获取的资源,利用浏览器自带的审查元素功能(F12)获得想要的资源
以知乎为例如下可见网页的各个元素的名称:
在这里插入图片描述
2.利用Jsoup进行解析:
这里主要的分析网站是https://www.zhihu.com/topic/19550874/hot
因为Android的网络操作需要在不能在主线程运行,可以使用Thread+Handler或者AsyncTask获取数据并在主界面刷新UI。
其次是数据的展示,将数据放在listView中即可,如果要加入下拉刷新或者上滑加载则需要额外的工作。
以下是关键代码:

/private class SearchTask extends AsyncTask<Void, Void, Boolean>
{
    Context context;
    Map.Entry<String,String>  topicURL;

    public SearchTask(Context context,Map.Entry<String,String> topicURL)
    {
        this.context = context;
        this.topicURL = topicURL;
    }

    @Override
    protected Boolean doInBackground(Void... voids)
    {
        Connection conn= Jsoup.connect("https://www.zhihu.com/topic/" + topicURL.getValue()+ "/hot");
        Document doc;
        try
        {
            doc = conn.get();
            Elements answerList = doc.select("div[class=ContentItem AnswerItem]");
            for (Element element : answerList)
            {
                Map<String, Object> map = new HashMap<>();
                //作者 标题
                JsonParser parser = new JsonParser();
                JsonObject data = parser.parse(element.attr("data-zop")).getAsJsonObject();
                String authorName = data.get("authorName").getAsString();
                String title = data.get("title").getAsString();
                map.put("title", title);
                //简略内容
                Elements spanContent = element.select("span[class=RichText CopyrightRichText-richText]");
                String minContent = spanContent.text();
                map.put("content", authorName+":"+minContent);
                //赞数
                Elements likeCountButton = element.select("button[class=Button VoteButton VoteButton--up]");
                String likeCount = likeCountButton.text();
                map.put("likeCount", likeCount+"点赞");
                //回答URL
                String url = element.getElementsByAttributeValue("itemprop", "url").get(2).attr("content");
                map.put("url", url);
                map.put("topic",topicURL.getKey());
                answersList.add(map);
            }
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        if (success) {
            listView_answer.onLoadComplete();
            adapter.notifyDataSetChanged();
            if(getUserVisibleHint())
                Toast.makeText(getActivity(), "加载完成", Toast.LENGTH_SHORT).show();
        } else {
            if(getUserVisibleHint())
                Toast.makeText(getActivity(),"连接服务器出错",Toast.LENGTH_SHORT).show();
        }
        mAuthTask = null;
    }

    @Override
    protected void onCancelled() {
        mAuthTask = null;
    }
}

private void setListView(View rootView)
{
    listView_answer = (LoadMoreListView) rootView.findViewById(R.id.listView_answer);
    listView_answer.setLoadMoreListen(this);
    swip = (SwipeRefreshLayout) rootView.findViewById(R.id.swip_index);
    swip.setOnRefreshListener(this);
    swip.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light,
            android.R.color.holo_green_light);
    adapter = new SimpleAdapter(getContext(),answersList,R.layout.answer_layout,
            new String[]{"title","content","likeCount","topic"},
            new int[]{R.id.textView_title,R.id.textView_content,R.id.textView_likeCount,R.id.textView_topic});
    listView_answer.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
        {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            Uri content_url = Uri.parse(answersList.get(i).get("url").toString());
            intent.setData(content_url);
            startActivity(intent);
        }
    });
    listView_answer.setAdapter(adapter);
}


参考地址:https://blog.csdn.net/chinastraw/article/details/79397892
至此,一个简单的Android网络爬虫就已经实现(layout文件省略)
作者:毛忠钦
原文地址:https://blog.csdn.net/qq_39388534/article/details/90721821

2016-07-26 16:22:44 katherine_qj 阅读数 4741
  • Python网络爬虫基础篇

    本课程主要给大家分享基于Python语言的网络爬虫基础篇体验,其中讲解爬虫原理介绍,urllib和requests爬虫库的使用,以及网络爬虫中的数据分析与信息提取。通过模拟Web的GET和POST请求来爬取数据,介绍如何应对各种常见反爬机制。后续还会有更深入的网络爬虫介绍体验,请大家持续关注。

    8303 人正在学习 去看看 CSDN讲师

嗯………………………………………
我也不懂爬虫是什么意思 就是从网页上扒数据吧应该是这样
所以这个demo抓取的是我们学校新闻网页的东西
看一下效果
这里写图片描述

抓的是这个网页 然后写了一个APP
是这样的
这里写图片描述这里写图片描述

把listview做成卡片式的了 然后配色弄的也很有纸质感啊啊啊
反正自己还挺喜欢的
然后就看看是怎么弄的
这里写图片描述

看一下每个类都是干啥的 :
MainActivity:主界面的Activity
MainAdapter:listview的适配器
NetWorkClass:链接网络 使用HttpClient发送请求、接收响应得到content 大概就是拿到了这个网页的什么鬼东西
还有好多就是一个html的代码 要解析这个
News:这个类里有两个属性 一个标题 一个是这个标题新闻点进去那个url;
NewsActivity:详细新闻界面
PullListView:重写了listview 具有下拉刷新和上拉加载功能

然后从oncreat()开始看:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        InitView();
        MainThread mt = new MainThread(newsUrl);
        final Thread t = new Thread(mt, "MainThread");
        t.start();

        pullListView.setOnRefreshListener(new PullListView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                isGetMore = false;
                MainThread mt = new MainThread(newsUrl);
                Thread t = new Thread(mt, "MainThread");
                t.start();

            }
        });

        pullListView.setOnGetMoreListener(new PullListView.OnGetMoreListener() {
            @Override
            public void onGetMore() {
                isGetMore = true;
                if (num > 1) {
                    MainThread mt = new MainThread(nextPage);
                    Thread t = new Thread(mt, "MainThread");
                    t.start();
                }

            }
        });
        pullListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(MainActivity.this,NewsActivity.class);
                intent.putExtra("url",list.get(position-1).getUrl());
                startActivity(intent);

            }
        });

    }

这个里面主要就是先初始化了数据
然后new了一个线程 因为涉及到了网络请求 所以我们要开线程去执行 然后有一些listview的下拉上拉点击的绑定
所以主要内容是在线程里面
再看线程之前 先看一下networkClass

package com.example.katherine_qj.news;

import android.net.http.HttpResponseCache;
import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Created by Katherine-qj on 2016/7/24.
 */
public class NetWorkClass {
    public String getDataByGet(String url){
        Log.e("qwe","content");
        String content ="";
        HttpClient httpClient = new DefaultHttpClient();
        Log.e("qwe","content1");
        /*使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
        1. 创建HttpClient对象。
        2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
        3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
        4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
        5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
        6. 释放连接。无论执行方法是否成功,都必须释放连接*/
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
           // HttpReponse是服务器接收到浏览器的请求后,处理返回结果常用的一个类。
            if(httpResponse.getStatusLine().getStatusCode() == 200) {
                /*getStatusLine()
               获得此响应的状态行。状态栏可以设置使用setstatusline方法之一,也可以在构造函数初始化*/
                InputStream is = httpResponse.getEntity().getContent();
                /*getEntity()
                获取此响应的消息实体,如果有。实体是通过调用setentity提供。*/
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                String line;
                while ((line = reader.readLine()) != null){
                    content += line;
                }
            }
        }catch (IOException e)
        {
            Log.e("http",e.toString());
        }
        Log.e("sdf",content);
        return  content;
    }
}

注释的很详细了
大概就是 有一个getDataByGet方法 然后接受一个url参数 经过一系列请求得到网页内容 返回一个content
下来就是使用这个类的线程了

 public class MainThread implements  Runnable{
        private String url;
        public MainThread(String url){
            this.url = url;
        }
        @Override
        public void run() {
            NetWorkClass netWorkClass =new NetWorkClass();//new 了一个network类
            content = netWorkClass.getDataByGet(url);//接收这个类返回的那个字符串也就是需要解析的那一串
            Log.e("qwe",content);
            handler.sendEmptyMessage(111);
        }
    }

就是利用这个线程去得到content 然后通过handle传递到主线程去解析

     private final android.os.Handler handler = new android.os.Handler(){
       public  void  handleMessage(Message msg){
           switch (msg.what){
               case 111:
                   analyseHTML();
                   if(isGetMore){
                        mainAdapter.notifyDataSetChanged();
           /*每一次notifyDataSetChange()都会引起界面的重绘。当需要修改界面上View的相关属性的时候,
             最后先设置完成再调用notifyDataSetChange()来重绘界面。*/
                   }else {
                       mainAdapter = new MainAdapter(MainActivity.this, list);
                       pullListView.setAdapter(mainAdapter);
                   }
                   pullListView.refreshComplete();
                   pullListView.getMoreComplete();
                   break;
           }
       }
     };

analyseHTML();
发现其实解析的东西在这个方法里面 所以 这里才是解析网页的东西啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊:

 public void analyseHTML(){
         if(content!=null){
             int x= 0;
             Document  document = Jsoup.parse(content);
             //解析HTML字符串
             if (!isGetMore) {
                 list.clear();
                 Element element = document.getElementById("fanye3942");//拿到fanye3942这个节点
                 String text = element.text();//得到这个节点的文本部分
                 System.out.print(text);
                 num = Integer.parseInt(text.substring(text.lastIndexOf('/') + 1, text.length() - 1));
                 System.out.print(num);
             }
                 Elements elements = document.getElementsByClass("c3942");//得到c3942这个节点中的所有子节点
                 while(true){
                    if(x==elements.size()){
                        System.out.print(elements.size());
                        break;//遍历到最后就退出
                    }
                     News news = new News();
                     news.setTitle(elements.get(x).attr("title"));//分别得到每一个子节点的需要的文本部分
                     news.setUrl(elements.get(x).attr("href"));
                    // list.add(news);
                     if (!isGetMore||x>10){
                         list.add(news);
                         if(x>=25){
                             break;
                         }//这个是因为我们学校的网页有重复
                     }
                     x++;

                 }
                 if (num>1){
                     nextPage = url+"/"+ --num+".htm";//因为有翻页这里得到了下一页的url在上拉的时候会开启线程去请求数据
                     System.out.println("qqqqqqqqqqq"+nextPage);
                 }

             }
         }

Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
所以android基于Jsoup 把content搞成Document 对象
然后就可以慢慢分解去拿了 然后拿哪里的数据就要看需要了
我开始一直不知道那些fanye3942 和c3942是啥 后来才知道是需要的数据的节点id或者class
这里写图片描述
就像这样
然后把每一次遍历的数据都加到集合里面 给listview绑定集合就好了

大概主页面就是这样 然后跳转页面 就是因为news里面还放入了每一个新闻点击之后的url所以传到NewsActivity中再利用相同的思路去解析显示就好了

package com.example.katherine_qj.news;

import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Created by Katherine-qj on 2016/7/25.
 */
public class NewsActivity extends Activity {
    private TextView textTitle;
    private TextView textEdit;
    private TextView textDetail;
    private String title;
    private String edit;
    private String  detail;
    private StringBuilder text;
    private String url;
    private Document document;
    private String  content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_news);
        InitView();
        url=getIntent().getStringExtra("url");
        Log.e("qqq",url);
        NewsThread newsThread = new NewsThread(url);

        final Thread t = new Thread(newsThread,"NewsActivity");
        t.start();

    }
    public void InitView(){
        textTitle =(TextView)findViewById(R.id.textTitle);
        textEdit =(TextView)findViewById(R.id.textEdit);
        textDetail = (TextView)findViewById(R.id.textDetail);
    }
    private final android.os.Handler handler = new android.os.Handler(){
      public  void handleMessage(Message msg){
          if(msg.what==1001){
              document = Jsoup.parse(content);
              analyseHTML(document);
              textTitle.setText(title);
              textEdit.setText(edit);
              textDetail.setText(text);
          }

      }
    };
    public class  NewsThread implements  Runnable{
        String url;
        public NewsThread(String url){
            this.url = url;
        }
        @Override
        public void run() {

            NetWorkClass netWorkClass = new NetWorkClass();
            content = netWorkClass.getDataByGet(url);
            System.out.print("qqq"+content);
            handler.sendEmptyMessage(1001);
        }


    }
    public void analyseHTML(Document document){
        if (document!=null){
            Element element = document.getElementById("nrys");
            Elements elements = element.getAllElements();
            title = elements.get(1).text();
            edit = elements.get(4).text();
            Element mElement = document.getElementById("vsb_content_1031");
            if(mElement != null) {
                Elements mElements = mElement.getAllElements();
                text = new StringBuilder();
                for (Element melement : mElements) {
                    if(melement.className().equals("nrzwys") || melement.tagName().equals("strong")){
                        continue;
                    }

                    if(!melement.text().equals(" ") && !melement.text().equals(""));{
                        text.append("  ").append(melement.text()).append("\n");
                    }
                    if (melement.className().equals("vsbcontent_end")) {
                        break;
                    }
                }
            }
        }
    }
}

然后这个demo就写好了 可以试着去再弄一些别的网页
有人吐槽我android代码写得好丑 和C语言一样
哈哈哈哈哈哈
现在想起来这个突然好好笑。

over!

Android网络爬虫

阅读数 1990

Jsoup实现网络爬虫抓取数据

博文 来自: qq_31034679
没有更多推荐了,返回首页