博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
爬虫学习日记(八)
阅读量:6904 次
发布时间:2019-06-27

本文共 4644 字,大约阅读时间需要 15 分钟。

维护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。

转载地址:http://vhvdl.baihongyu.com/

你可能感兴趣的文章