Java网络爬虫基础概述

Java网络爬虫基础

Http基础

网络资源一般是Web服务器上的一些各种格式的文件,通过Http协议传输互联网上的数据.

在Java中,通常通过URL标出网络资源的位置和Web服务器建立链接,获取网页源代码.
爬虫程序通过域名服务(Domain Name Serive,简称 DNS)取得域名对应的IP地址,它首先连接到一个DNS服务器上,由DNS服务器返回域名对应的IP地址.DNS把解析到错误的域名叫做DNS劫持.

Linux常用如下命令来分析DNS解析的问题(以下命令暂以百度为例)

  • dig命令

$ dig www.baidu.com; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.5 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60412
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:
;www.baidu.com.                 IN      A;; ANSWER SECTION:
www.baidu.com.          419     IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       149     IN      A       110.242.68.3
www.a.shifen.com.       149     IN      A       110.242.68.4;; Query time: 1 msec
;; SERVER: 183.60.83.19#53(183.60.83.19)
;; WHEN: Wed Mar 23 22:16:36 CST 2022
;; MSG SIZE  rcvd: 90
  • nslookup命令

$ nslookup www.baidu.comServer:         183.60.83.19
Address:        183.60.83.19#53Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
Name:   www.a.shifen.com
Address: 110.242.68.4
Name:   www.a.shifen.com
Address: 110.242.68.3

在Windows下可以以如下方法查看路由情况.

> tracert -d www.baidu.com通过最多 30 个跃点跟踪
到 www.a.shifen.com [110.242.68.3] 的路由:1    <1 毫秒   <1 毫秒    1 ms  192.168.1.12     1 ms     1 ms     1 ms  192.168.18.13     4 ms     3 ms     2 ms  111.161.232.14     3 ms     2 ms     2 ms  117.8.159.2055     3 ms     3 ms     3 ms  117.10.223.1176     *        *        *     请求超时。7     9 ms     9 ms     9 ms  110.242.66.1868     *        *        *     请求超时。9     *        *        *     请求超时。10     *        *        *     请求超时。11     *        *        *     请求超时。12     *        *        *     请求超时。13     9 ms     9 ms     9 ms  110.242.68.3跟踪完成。

通过Java来获取一个网站所有的IP

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;public class Main {public static void main(String[] args){try {List<String> ipList = new ArrayList<>();InetAddress[] addressesList = InetAddress.getAllByName("www.sina.com.cn");for(InetAddress address:addressesList){ipList.add(address.getHostAddress());System.out.println(address.getHostAddress());}}catch (Exception e){e.printStackTrace();}}
}

URL可选择一个指定的端口,它用于建立远程主机TCP(Transmission Control Protocol)连接的端口号,如果未指定端口则默认使用默认端口,80端口.

URI

URI包括URL和URN,但是URN并不常用.URL由3部分组成:

https://finance.sina.com.cn/stock/
协议名 主机名 资源路径
http finance.sina.com.cn stock

Http规范定义了8种可能的请求方法,爬虫经常用到的有以下三种:

方法 说明
GET 检索URI种标识资源的一个简单请求
HEAD 与GET方法相同,服务器只返回状态行和头标,不返回请求文档
POST 服务器接受被写入客户端输出流中的数据的请求,可以用POST方法来提交表单参数

发送给Web服务器的请求头参数

请求头参数 含义
Accept:text/plain,text/html 说明了可以接收文本类型的信息
Referer:https://www.sina.com.cn/ 此值告诉服务器访问来自于哪个页面,服务器由此可以获得一些信息用于处理,有的网站会利用此参数用于防止图片盗链
Keep-alive:115 是指在同一个链接中发出和接收多次HTTP请求

Web服务器处理返回的状态码分类

状态码 类型 作用
1xx 信息响应类 表示接收到请求并且继续处理
2xx 处理成功响应类 表示动作被成功接收、理解和接受
3xx 重定向响应类 为了完成指定动作,必须接受进一步处理
4xx 客户端错误 客户端请求包含语法错误或者不能正确执行
5xx 服务端错误 服务器不能正确执行一个正确的请求

HTTP常用状态码

状态代码 代码描述 处理方式
200 请求成功 获得响应的内容,进行处理
201 请求完成,结果是创建了新资源.新创建资源的URI可在响应的实体中得到 爬虫不会遇到
202 请求被接受,但处理尚未完成 阻塞等待
204 服务器端已经实现了请求,但没有返回新的信息,如果客户是用户代理,则无须为此更新自身的文档视图 丢弃
300 该状态码不被HTTP/1.0的应用程序直接使用,只是作为3xx类型回应的默认解释,存在多个可用的被请求资源 若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃
301 请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 重定向到分配的URL
302 请求到的资源在一个不同的URL处临时保存 重定向到临时的URL
304 请求的资源未更新 丢弃
400 非法请求 丢弃
401 未授权 丢弃
403 禁止 丢弃
404 没有找到 丢弃
500 服务器内部错误 丢弃
502 错误网关 丢弃
503 服务器暂时不可用 丢弃

Get Post Head方法的基础Java代码

Maven依赖:

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version> 
</dependency>
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.3</version>
</dependency>

Head:

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpHead;import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;import java.net.URI;public class Head {private String url="";public void setUrl(String url){this.url=url;}public void doHead() throws Exception{CloseableHttpClient closeableHttpClient= HttpClientBuilder.create().build();URI uri=new URI(url);HttpHead method=new HttpHead(uri);HttpResponse response=closeableHttpClient.execute(method);Header[] s=response.getAllHeaders();for(int i=0;i<s.length;i++){Header hd=s[i];System.out.println("Header Name: "+hd.getName()+"    "+"Header Value: "+hd.getValue());}}
}

Get:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Get {private String url="";public void setUrl(String url){this.url=url;}private String cookie="";public void setCookie(String cookie){this.cookie=cookie;}private Map header=new HashMap();public void addHeader(String key,String value){header.put(key,value);}private String html="";public String doGet() throws Exception{CloseableHttpClient closeableHttpClient= HttpClientBuilder.create().build();HttpGet httpGet=new HttpGet(url);/* 传参 */
//        httpGet.addHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
//        httpGet.setHeader("Cookie","HttpOnly; UM_distinctid=176d650b687fc-0a035a289264ec-1e2e1b0b-1fa400-176d650b688c77; Hm_lvt_080dabacb001ad3dc8b9b9049b36d43b=1609913383; f_city=%E5%A4%A9%E6%B4%A5%7C101030100%7C; Wa_lvt_1=1609913383; CNZZDATA1278536588=1934037795-1609908526-%7C1609918974");Set<Map.Entry<String,String>> entrySet=header.entrySet();for(Map.Entry<String,String> entryset:entrySet){httpGet.setHeader(entryset.getKey(),entryset.getValue());}HttpResponse response=closeableHttpClient.execute(httpGet);HttpEntity entity=response.getEntity();if(entity!=null){html= EntityUtils.toString(entity,"UTF-8");EntityUtils.consume(entity);}return html;}
}

Post:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.ByteArrayBuffer;import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.*;public class Post {private String url="";public void setUrl(String url){this.url=url;}private String cookie="";public void setCookie(String cookie){this.cookie=cookie;}private Map<String,String> header=new HashMap<>();public void addHeader(String key,String value) {header.put(key,value);}private List<NameValuePair> nameValuePairs=new ArrayList<NameValuePair>();public void addNameValuePairs(String key,String value){nameValuePairs.add(new BasicNameValuePair(key,value));}public String doPost() throws Exception{CloseableHttpClient httpClient= HttpClientBuilder.create().build();HttpPost httpPost=new HttpPost(url);Set<Map.Entry<String,String>> entrySet=header.entrySet();for(Map.Entry<String,String> entryset:entrySet){httpPost.setHeader(entryset.getKey(),entryset.getValue());}/* 传参 */
//        httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
//        httpPost.setHeader("Cookie",cookie);
//        nameValuePairs.add(new BasicNameValuePair("page","1"));
//        nameValuePairs.add(new BasicNameValuePair("rp","12"));
//        nameValuePairs.add(new BasicNameValuePair("sortname","_CreateTime"));
//        nameValuePairs.add(new BasicNameValuePair("sortorder","desc"));
//        nameValuePairs.add(new BasicNameValuePair("query",""));
//        nameValuePairs.add(new BasicNameValuePair("qtype",""));
//        nameValuePairs.add(new BasicNameValuePair("queryid","flowmystart"));
//        nameValuePairs.add(new BasicNameValuePair("condition","_UserName='53c6b305-5bea-450a-b7a1-11ce1feab4b2'"));httpPost.setHeader("cookie",cookie);httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));HttpResponse response=httpClient.execute(httpPost);HttpEntity entity=response.getEntity();InputStream inputStream=entity.getContent();BufferedInputStream bufferedInputStream=new BufferedInputStream(inputStream);ByteArrayBuffer byteArrayBuffer=new ByteArrayBuffer(20);int current=0;while((current=bufferedInputStream.read())!=-1){byteArrayBuffer.append((byte) current);}String text=new String(byteArrayBuffer.toByteArray());System.out.println(text);return text;}
}

Published by

风君子

独自遨游何稽首 揭天掀地慰生平