爬虫学习日记(八)

维护WHLCCrawler:

这个爬虫之前跑不通的原因:
1.之前的作者写的工具类,里面的重定向出现了问题,没有重定向成功。
解决方案:
我重新声明一个httpclient,不过用的还是defaultHttpclient的方式,这个方式早已经过时了,但是我需要他前面操作然后获取他的cookie,用最新的方式的话,全部都要大改,所以我就跟着他先用着过时的方法,把之前进行操作的cookie放进去。放进去以后,手动完成重定向,他返回302状态后,在返回的response中取出header,在header中取出location,把location当做新的url了,用之前的parma再重新访问一遍,如果返回的是301则重复上诉操作。


				HttpResponse res = client.execute(post);
				int status = res.getStatusLine().getStatusCode();
				if(res.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY){
					Header[] header ;
					header = res.getHeaders("Location");
					String location = header[0].getValue();
					HttpPost post2 = new HttpPost(location);
					post2.setEntity(entity);
					DefaultHttpClient client2 = httpClientProxy.generateClient();
					client2.setCookieStore(httpClientProxy.getCookieStore());
					HttpResponse res2 = client2.execute(post2);
					int status2 = res2.getStatusLine().getStatusCode();
					
					if(res2.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_PERMANENTLY){
						Header[] header2 ;
						header2 = res2.getHeaders("Location");
						String location2 = header2[0].getValue();
						HttpPost post3 = new HttpPost(location2);
						post3.setEntity(entity);
						DefaultHttpClient client3 = httpClientProxy.generateClient();
						client3.setCookieStore(httpClientProxy.getCookieStore());
						HttpResponse res3 = client3.execute(post3);
						int status3 = res3.getStatusLine().getStatusCode();
						routeScheduleResponse = EntityUtils.toString(res3.getEntity());
						System.out.print(routeScheduleResponse);
					}	
				}
复制代码

2.返回的response是乱码
解决方案:观察response header里面,他的contenttype是gzip,就说明了网站把数据进行了压缩,我们获取到是压缩过得数据,想要获得正确的数据,就必须解码,解码成utf-8。因为原作者是直接返回的String,所以我在他原工具类里面,添加了一个判断,判断header里面的contenttype是否为gzip,是的话,就进行转码,不是的话,也不影响之前的功能。
转码实现方式:因为返回来的是String,先用inputStream输入流来接收他,再传进去gzip输入流。

	    			 InputStream in = response.getEntity().getContent();
	    			 GZIPInputStream gzin = new GZIPInputStream(in);
	    			 InputStreamReader isr = new InputStreamReader(gzin,"utf-8");
	    			 StringBuilder buffer = new StringBuilder();
    		         BufferedReader reader = null;
    		         reader = new BufferedReader(isr);
    		         String line = null;
    		         while ((line = reader.readLine()) != null) {
    		             buffer.append(line + "\n");
    		        }
    		        reader.close();
    		        body = buffer.toString();
复制代码

3.特定的por和特定的fnd不能返回正确的结果 解决方案:因为这个爬虫之前的逻辑是,模拟输入出发国家,模拟输入出发城市,再模拟目的国家,然后把进行完这些操作的cookie传给要进行submit操作的client就能返回正确的结果。而当进行模拟输出出发国家时,他会返回默认的出发国家,如果我们刚好给的数据就是这个默认的国家的话,就不用进行模拟出发城市的操作,而我之前是进行的,可能这个cookie就是错的,他往下面执行,就不能获取正确的结果。
所以我在进行模拟输入出发城市的时候,会获取默认城市,跟我要搜索的城市进行比较。

private boolean checkFromCity(String response,String fromCity) {
		// TODO Auto-generated method stub
		Parser parser;
		try {
			parser = Parser.createParser(new String(response.getBytes(), encode_UTF8), encode_UTF8);
			parser.setEncoding(parser.getEncoding());
			String defaultOption = parserOptionNode(parser, CSS_OPTION_SELECTED, ATTRIBUTE_VALUE);
			if(defaultOption.equals(fromCity)){
				return true;
			}else{
				return false;
			}
		} catch (UnsupportedEncodingException e) {
			throw new UnRetriableException(RoboticsException.TYPE_UNKNOWN, "parser defaultOption from search index page meet encoding error!", e);
		} catch (ParserException e) {
			throw new UnRetriableException(RoboticsException.TYPE_UNKNOWN, "parser defaultOption from search index page meet parser error!", e);
		}
	}

	private String parserOptionNode(Parser parser, String css, String attribute) throws ParserException {
		// TODO Auto-generated method stub
		NodeList searchResultNodes = extractNodesByCss(parser, css);
		if (null == searchResultNodes || searchResultNodes.size() < 1) {
			throw new RetriableException(RoboticsException.TYPE_UNEXPECTED_RESPONSE, "Can not get " + css + " element from route search page!", null);
		}
		OptionTag inputTag = (OptionTag) searchResultNodes.elementAt(1);
		String value = inputTag.getAttribute(attribute);
		return value;
	}
	private NodeList extractNodesByCss(Parser parser, String css) throws ParserException {
		parser.reset();
		CssSelectorNodeFilter searchResultFilter = new CssSelectorNodeFilter(css);
		NodeList searchResultNodes = parser.extractAllNodesThatMatch(searchResultFilter);
		return searchResultNodes;
	}
复制代码

这里学到一个很重要的东西,怎么把页面转成可解析的html然后根据css的值来取value。
首先把response转成parse,parse是一个HTML解析器。CssSelectorNodeFilter searchResultFilter = new CssSelectorNodeFilter(css);這一句相当于设置一个过滤,NodeList searchResultNodes = parser.extractAllNodesThatMatch(searchResultFilter);然后装载,把符合条件的的节点放在NodeList中。然后我要的节点在索引1的位置,取出索引1的的值,我取得节点标签是option,就用optionTag来接收,然后用.getAttribute(attribute);来获取这个节点里面的值,我要获取的是他的value,所以atribute的值是value。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值