为了账号安全,请及时绑定邮箱和手机立即绑定

Java 爬虫 - 自己手动写网络爬虫

标签:
Java Python

1、全面剖析网络爬虫

    你知道百度、谷歌是如何获取数以亿计的网页并且实时更新的吗?你知道在搜索领域人们常说的spider吗,本文章将介绍网络爬虫的方方面面,读完之后希望你直接能写出来一个网络爬虫,随意抓取互联网上面你感兴趣的任何东西。

    既然百度、谷歌这些搜索引擎巨头已经帮我们抓取了互联网上面大部分的信息,为什么我们自己还要写爬虫呢?因为在现实生活中信息的需求是广泛的,在企业中,爬虫抓取下来的信息可以做为数据仓库多维度展示的数据源,也可以作为数据挖掘的来源,甚至有人为了炒股,抓取股票信息。既然从美国中情局到普通老百姓都需要,那还等什么,干就完了。

1.1通过指定的URL抓取网页内容

   Java语言是为网络而生的编程语言,它把网络资源看成是一种文件,它对网络资源的访问和对本地文件的访问一样方便,它把请求和响应封装成流,因此我们可以根据相应内容,获得响应流,之后从流中按字节读取数据,例如,Java.net.URL有一个默认的构造函数,使用URL地址作为参数,构造URL对象。

URL pageUrl = new URL(path);

    接着,可以通过获得的URL对象来取得网络流,

inputStream stream = pageUrl.openStream();

    在实际项目中,网络环境比较复杂,因此,Java.net包中的api来模拟IE客户端的工作,代码量非常大,需要处理HTTP返回的状态码,设置http代理,处理HTTPS协议等工作。为了便于程序的开发,实际开发中常常使用Apache的HttpClient。

    例如:

//创建一个客户端,类似于打开一个浏览器		
HttpClient httpClient = new HttpClient();	

//创建一个get方法,类似于浏览器中输入地址		
GetMethod getMethod = new GetMethod(" 
//回车,获取响应代码		
int statusCode = httpClient.executeMethod(getMethod);		
System.out.println(statusCode);		
		
//查看命中情况		
System.out.println("response= " + getMethod.getResponseBodyAsString());	

//释放		
getMethod.releaseConnection();

    在这个实例中,只是简单的返回网页内容,在现实项目中,通常需要把返回的内容写到本地文件并保存。最好还要关闭网络连接,避免资源消耗。

   这个日子使用get方式来访问web资源,get请求方式把需要传递给服务器的参数作为URL的一部分传递给服务器,但是,HTTP协议本身对URL字符串长度有所限制,因此不能传递过多的参数,为了避免这个问题,可以使用HttpClient的POST方法。

//创建一个客户端,类似于打开一个浏览器
HttpClient httpClient = new HttpClient();	
		
//创建一个post方法,类似于浏览器中输入地址		
PostMethod postMethod = new PostMethod(" 

//使用数组传递参数		
NameValuePair[] valuePairs = new NameValuePair[2];		
valuePairs[0] = new NameValuePair("前段开发", "HTML");		
valuePairs[1] = new NameValuePair("后端开发", "JAVA");	
			
//设置参数		
postMethod.addParameters(valuePairs);	
			
//回车,获取响应代码		
int statusCode = httpClient.executeMethod(postMethod);		
System.out.println(statusCode);	
			
//查看命中情况		
System.out.println("response= " + postMethod.getResponseBodyAsString());		
System.out.println("NameValuePair[0] " + postMethod.getParameters()[0]);		
System.out.println("NameValuePair[1] " + postMethod.getParameters()[1]);
	
//释放		
postMethod.releaseConnection();

结果:
200
NameValuePair[0] name=前段开发, value=HTML
NameValuePair[1] name=后端开发, value=JAVA

    有时,我们执行爬虫程序的机器不能直接访问WEB资源,而是需要通过代理服务器去访问,HTTPClient对代理服务器也有很好的支持。例如:

//创建HttpClient相当于打开一个代理	   
HttpClient httpClient = new HttpClient();
	   
//设置代理服务器的IP和端口	   
httpClient.getHostConfiguration().setProxy("192.168.0.1", 8888);
	   
//告诉HttpClient,使用抢先认证,否则你会收到你没有资格的恶果	   
httpClient.getParams().setAuthenticationPreemptive(true);	   	   
//httpClient.getParams().setParameter(CredentialsProvider.PROVIDER,
 new MyCredentialsProvider());	  
 	   
//设置代理服务器的用户名密码	  
httpClient.getState().setProxyCredentials(new AuthScope("192.168.0.1",
 AuthScope.ANY_PORT,AuthScope.ANY_REALM),
 new UsernamePasswordCredentials("username","Password"));

    上面的例子详细解释了如何使用HTTPClient设置代理服务器,如何在局域网访问WEB资源。

1.2处理HTTP状态码

  当状态码是2XX的时候,我们只需要处理200和202两种状态码,其他的可以采用简单的丢弃处理就可以解决。200的状态码标识成功,可以直接进行网页抓取,例如:

if(statsuCode == HttpStatus.SC_OK)
{
    input = postMethod.getResponseBodyAsString();
    //得到文件名
    String fileName = path.substring(path.lastIndexOf('/')+1);
    //获取文件输出流
    outPut = new FileOutputStream(fileName);
    //输出到文件
    int tempValue = -1;
    while((tempValue = input.read() > 0 )){
        output.write(tempValue );
    }
}

    202的响应码,表示请求已经接受,服务器再做处理。

   当返回值状态码为3XX时,通常进行转向,例如:

 //处理状态为3XX的  
 if(statusCode==HttpStatus.SC_MOVED_TEMPORARILY||  
    statusCode==HttpStatus.SC_SEE_OTHER||  
    statusCode==HttpStatus.SC_TEMPORARY_REDIRECT){  
 //读取新的URL地址  
    Header header=getMethod.getRequestHeader("location");  
    if(header!=null){  
          String newUrl=header.getValue();  
          if(newUrl==null||newUrl.equals("")){  
          newUrl="/";  
          //重定向处理  
          GetMethod method=new GetMethod(newUrl);  
          }  
     }  
                  
}

下面的博客地址是之前写的用Python爬虫的具体执行逻辑,内容很丰富,介绍了python爬虫主要的五个模块:

  • 爬虫启动入口模块,

  • URL管理器存放已经爬虫的URL和待爬虫URL列表,

  • html下载器,

  • html解析器,

  • html输出器      

同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

https://www.cnblogs.com/wenhongyu/p/7157492.html


      【不是每一个问题都是钉子, 不是每一个解决方案都是锤子】


原创首发于慕课网
作者:Wenhy
来源:慕课网


点击查看更多内容
15人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
15
获赞与收藏
106

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消