简单爬虫知识

爬虫是什么
爬虫又叫网络爬虫,是一种运行在互联网上为了获取数据的自动化程序。

互联网上有哪些数据值得爬取?
公司内部数据

  • 业务数据,公司使用BI(Business Intelligence)、CRM系统、ERP系统、邮件系统等产生的数据;
  • 财务数据,其中包括公司的支出、采购、收入等多项与公司日常运作有关的数据;
  • 用户数据,无论是网站、APP还是游戏,用户注册都会填写邮箱、电话、身份证号码等数据,这些数据其实非常有价值,此外还要加上用户使用公司产品留下的行为数据。
  • 历史数据,公司沉淀下来的其他各种数据。

外部数据

  • 社交网站数据,包括微信、微博、人人网、Twitter、Facebook、LinkedIn等社交媒体上的数据。
    说明:社交数据部分是可以爬取的,另外一部分是需要运营方授权的。
  • 线下采集数据,包括Wifi热点数据、地图数据等。
    说明:这一块目前做的公司比较少,但同时也比较有价值。
  • 政府开放数据,包括企业征信数据、企业注册数据、法院公示数据、公共交通数据等。
    说明:如果你想要找的话,可到对应政府网站下载。
  • 智能设备数据,包括智能设备、传感器数据。
    说明:你知道吗?一部智能手机,至少拥有8个传感设备。
  • 网络爬虫数据,包括互联网上所有可以爬回的数据,文字、视频、图片其实也是数据,而且是非结构化数据。
  • 企业交易数据,包括商家流水数据、支付宝交易数据、信用卡消费数据等等。
    说明:目前这一部分数据是最难获取的,因为数据就是宝贵的资产。
  • 企业开放数据,比如微博开放了商业数据API,腾讯开放了腾讯云分析SDK上报的应用数据,高德地图开放了LBS数据等等。
    说明:如果想找更多的数据API,我推荐你去数据堂、聚合数据这两家网站上看一下,上面有大量的API接口。
  • 其它数据,比如天气数据、交通数据、人口流动数据、位置数据等等。
    说明:只有想不到没有弄不到。

总结

大数据即使整合完公司内部外部数据进行大数据存储,然后通过清洗,标注、去重、去噪、关联等过程可以将数据进行结构化,也可以进行大数据挖掘和数据分析,再以数据可视化呈现结果,打通数据孤岛形成数据闭环,将数据转换成“石油”和“生产资料”,最后应用到我们日常的生活、学习和工作中去。
爬虫爬取的数据有什么用
* 和搜索引擎结合使用
* 进行数据分析
对数据进行分析,提取有价值的信息(偏好、位置)
什么是数据分析?
对已经存在的数据进行归类和总结,得到有价值的信息。

  • 案例说明
    • Wifi 定位一个人 分析wifi周边的人流量
    • 获取你的网页浏览记录 分析偏好

总结
互联网我们的爬虫不仅仅是为搜索而存在的,大多数时候是为数据分析而存在的。
爬虫开发是大数据分析的一个基本条件。

爬虫的简单分类
* 通用爬虫:百度 爬取互联网所有数据的爬虫叫做通用爬虫
* 垂直爬虫:为做数据分析而爬取特定数据的爬虫叫做垂直爬虫。
* 淘宝评论爬虫
* 淘宝商品爬虫
* 分类的标准:根据数据量或者业务范围
总结
在互联网上,大多数都是垂直爬虫,也就是值爬取一定范围内的数据。
爬虫的运行原理

你自己如何获取网页上的数据?

  • 1、打开一个网页
  • 2、复制 标题 新闻内容 下载图片

爬虫爬取一个页面的流程

  • 3、指定一个URL
  • 4、发起一个网络请求 HTTP
  • 5、得到一个HTML文档
  • 6、解析HTML文档

爬虫爬取多个页面

  • 1、指定很多个URL
    数据结构 list
  • 2、从list中依次拿取url
    • 发起一个网络请求 HTTP
    • 得到一个HTML文档
    • 解析HTML文档
      • 顺便解析出其他URL
      • 将解析的URL存放到等待爬取的URL中

爬虫的原理图

步骤说明:
* 1、将一个种子URL存放到队里中
* 2、从队列中读取一个URL
* 3、发起网络请求(上图4-5-6步)
* 3.1、域名解析,得到IP地址
* 3.2、发起HTTP请求
* 3.3、下载页面
* 4、解析HTML文档(上图7-8-9步)
* 解析HMTL文档获取网页中所有URL
* 分页页面是否爬取过
* 如果没有爬取就放入待抓取的URL队里中

分析网络爬虫开发技术

需求:爬取一个页面的内容
* 1、人的操作:找到URL 输入到浏览器的地址栏 回车
浏览器帮我们发送了网络请求
技术实现:如何发送网络请求
* Socket(服务端、客户端)
* HttpURLConnection(用来访问http连接)
* HttpClient (操作网络请求更快的API) 学会HTTPClient

三个技术点之间的关系: 
* Socket原生底层(ip、port) 除非我们自己开发游戏服务器
* HttpURLConnection JDK提供的一套访问Http资源的API
* HttpClient 基于HttpURLConnection高度封装,不需要关注网络请求的细节。
  • 2、人的操作:得到一个HTML文档二进制数据
    浏览器帮我们解析了二进制数据,将网页按照HTML的标准呈现给我们
    技术实现:如何获取HTML页面
    Inputstream 转化成 String 得到HTML纯文本数据。
    知道HTML文档格式,因为我们要进一步解析数据

  • 3、人的操作:人为的复制、粘贴操作
    通过代码来解析HTML文档,获取有用的数据。
    技术实现:如何解析数据

    • Document对象

    • JSOUP 为解析HTML而生。

    技术点之间的关系:
    Document对象是原生的API,Jsoup是更高级的框架。

总结:爬虫开发的两个核心技术
* Httpclient:帮助我们更好发送网络请求
* Jsoup:帮助我们更好的解析html。

如何模拟浏览器进行网络请求
* 1、HTTP协议
* 2、Java网络请求原生API
* 2.1、Java网络请求原生API-Get请求
* 2.2、Java网络请求原生API-Post请求
* 3、使用HttpClient进行网络请求
* 3.1、使用HttpClient进行Get请求
* 3.2、使用HttpClient进行POST请求
* 3.3、使用HttpClient进行Get请求-简单
* 3.4、使用HttpClient进行POST请求-简单

1、HTTP协议

HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。

客户端向服务器发送一个请求,请求头包含请求的方法、URL、协议版本、以及包含请求修饰符、客户信息和内容的类似于MIME的消息结构。

服务器以一个状态行作为响应,响应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。

通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个指示头域结束的空行和可选的消息体组成。

HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

HTTP常见状态码 所有的状态码:百度百科

2、Java网络请求原生API

HttpUrlConnection

Get 方式请求网络基本流程
* 给定一个域名:www.itcast.cn
* 创建URL对象
* 通过URL对象打开一个连接
* 判断请求状态是否等于200
* 输入流:获取服务端的响应数据
* 使用BufferReader读取数据
* 关闭流

Post 方式请求网络基本流程
* 给定一个域名:www.itcast.cn
* 创建URL对象
* 通过URL对象打开一个连接
* 设定Post请求方式
* 指定 requestMethod为post
* 打开 conn.setDoOutput(true)
* 提交数据到服务器
* 获取outputStream
* 写出数据
* flush and close
* 判断请求状态是否等于200
* 输入流:获取服务端的响应数据
* 使用BufferReader读取数据
* 关闭流

2.1、Java网络请求原生API-Get请求

使用原生API发送Get请求

public class Get {
    public static final String USER_AGENT = "Mozilla/5.0";
    public static void main(String[] args) throws IOException {
        //1、准备要访问的URL
        String url = "http://www.itcast.cn";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //2、设置Http协议的参数
        // optional default is GET
        con.setRequestMethod("GET");
        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);

        //3、发起HTTP请求,获取状态码
        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'GET' request to URL : " + url);
        System.out.println("Response Code : " + responseCode);

        //4、如果是正常相应,读取数据
        if (responseCode == 200) {
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            //print result
            System.out.println(response.toString());
        }
    }
}

2.2、Java网络请求原生API-Post请求

使用原生API发送Post请求

package cn.itcast.pcss.base.httpurlconnection;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Post {
    public static final String USER_AGENT = "Mozilla/5.0";
    public static void main(String[] args) throws IOException {
        String url = "http://sspc.itcast.cn/login/login.html";
        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        //add reuqest header
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", Post.USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        String urlParameters = "username=maoxiangyi&password=&maoxiangyi&reURL=http://shop.itcast.cn/item/itemList.html";

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParameters);
        wr.flush();
        wr.close();

        int responseCode = con.getResponseCode();
        System.out.println("\nSending 'POST' request to URL : " + url);
        System.out.println("Post parameters : " + urlParameters);
        System.out.println("Response Code : " + responseCode);
        if (responseCode == 200) {
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            System.out.println(response.toString());
        }
    }
}

3、使用HttpClient进行网络请求

本节介绍使用HttpClient进行网络请求。

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

HtppClient 官网

为什么有HttpClient
* 超文本传输协议(HTTP)可能是当今互联网上使用的最重要的协议
* 虽然java.net包提供了通过HTTP访问资源的基本功能,但它并没有提供许多应用程序所需的完全灵活性或功能

使用HttpClient的maven依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.5.2</version>
</dependency

3.1、使用HttpClient进行Get请求

使用HttpClient进行Get请求

  • HttpClients.createDefault 创建一个客户端
  • HttpGet 创建一个Get请求
  • httpclient.execute(httpGet) 执行一个请求
  • CloseableHttpResponse 获取返回值
    • getStatusLine 获取状态信息
    • EntityUtils 操作返回内容

代码实现

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.Charset;

/**
 * Created by maoxiangyi on 2017/6/26.
 */
public class SimpleGet {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://sspc.itcast.cn");
        CloseableHttpResponse response = httpclient.execute(httpGet);
        System.out.println(response.getStatusLine());
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            String html = EntityUtils.toString(entity, Charset.forName("utf-8"));
            System.out.println(html);
        }
        response.close();
    }
}

3.2、使用HttpClient进行Post请求

使用HttpClient进行Post请求

  • HttpClients.createDefault 创建一个客户端
  • HttpPost 创建一个Post请求
    • UrlEncodedFormEntity 封装表单信息
  • httpclient.execute(HttpPost) 执行一个请求
  • CloseableHttpResponse 获取返回值
    • getStatusLine 获取状态信息
    • EntityUtils 操作返回内容

代码实现:

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by maoxiangyi on 2017/6/26.
 */
public class SimplePost {
    public static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("http://shop.itcast.cn/login/login.html");
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("username", "maoxiangyi"));
        nvps.add(new BasicNameValuePair("password", "maoxiangyi"));
        nvps.add(new BasicNameValuePair("reURL", "http://shop.itcast.cn/item/itemList.html"));
        httpPost.setEntity(new UrlEncodedFormEntity(nvps));
        CloseableHttpResponse response = httpclient.execute(httpPost);
        System.out.println(response.getStatusLine());
        //如果登录之后需要重定向,获取重定向的值
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            System.out.println(header);
        }
        if (response.getStatusLine().getStatusCode() == 302) {
            Header[] locations = response.getHeaders("Location");
            String url = locations[0].getValue();
            System.out.println(url);
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpResponse response1 = httpclient.execute(httpGet);
            if (response1.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response1.getEntity();
                String html = EntityUtils.toString(entity, Charset.forName("utf-8"));
                System.out.println(html);
            }
            response1.close();
        }
        response.close();
    }
}

3.3、使用HttpClient进行Get请求-简单方式

使用HttpClient进行Get请求-简单方式

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * Created by maoxiangyi on 2017/6/26.
 */
public class EasyGet {
    public static void main(String[] args) throws IOException {
        String html = Request.Get("http://shop.itcast.cn").execute().returnContent().asString(Charset.forName("UTF-8"));
        System.out.println(html);
    }
}

3.4、使用HttpClient进行Post请求-简单

使用HttpClient进行Post请求-简单方式

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;

/**
 * Created by maoxiangyi on 2017/6/26.
 */
public class EasyPost {
    public static void main(String[] args) throws IOException {
        HttpResponse response = Request.Post("http://shop.itcast.cn/login/login.html")
                .bodyForm(Form.form().add("username", "maoxiangyi").add("password", "maoxiangyi").add("reURL","http://shop.itcast.cn/item/itemList.html").build())
                .execute().returnResponse();
        if (response.getStatusLine().getStatusCode() == 302) {
            Header[] locations = response.getHeaders("Location");
            String url = locations[0].getValue();
            System.out.println(url);
            HttpGet httpGet = new HttpGet(url);
            String html =  Request.Get(url).execute().returnContent().asString(Charset.forName("UTF-8"));
            System.out.println(html);
        }
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值