朋友們,很久不見了。最近忙着其餘事情,一直沒有到博客園轉轉。大家還好嗎?javascript
分享最近項目裏面的一小段代碼吧。html
描述:因爲某種須要,須要抓取某些特定網站上的信息,其中有一些網站是須要登陸後才能抓取信息的。這就牽扯到如何模擬登錄,登錄後又應該進行哪些處理能夠爬取其餘頁面的信息。java
通常來講,須要登陸的網站都沒有禁用cookie,(若是對cookie和http協議不瞭解,請自行百度),通常模擬登錄都是利用這一特性進行的。ajax
主要過程如圖所示:apache
本人項目中代碼也是大概這麼一個過程,我利用了開源工具httpClient 。由於該工具對HTTP協議進行了很好的封裝和管理,固然也實現了http中全部的協議,好比get,post等等。json
/* * 測試代碼 */
public static void main(String[] args) throws ClientProtocolException, IOException { // TODO Auto-generated method stub
String message="Hello,World!"; DefaultHttpClient client=getHttpClient(); if(sendMessage(client, message)) System.out.println("發送成功"); else System.out.println("發送失敗"); } /*** * 獲得一個登錄後添加了cookie的鏈接。 * * @author http://www.cnblogs.com/xiaoyi115/ * */
public static DefaultHttpClient getHttpClient() throws ClientProtocolException, IOException{ DefaultHttpClient client=new DefaultHttpClient(); List<NameValuePair> nvps=getNameValuePairs(); String uri="http://passport.cnblogs.com/login.aspx"; List<Cookie> cookies=getCookies( nvps, uri); for (Cookie cookie : cookies) { client.getCookieStore().addCookie(cookie); } return client; } /*** * 顯示發送的消息是否成功 * @param client 一個鏈接 * @param message 須要發送的消息 * @return 返回發送是否成功 * @author http://www.cnblogs.com/xiaoyi115/ * */
public static boolean sendMessage(DefaultHttpClient client,String message) throws ParseException, IOException{ HttpPost post=new HttpPost("http://home.cnblogs.com/ajax/ing/Publish"); post.addHeader("Accept", "application/json, text/javascript, */*; q=0.01"); post.addHeader("Accept-Encoding", "gzip,deflate,sdch"); post.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36"); post.addHeader("Content-Type", "application/json; charset=UTF-8"); post.addHeader("Origin", "http://passport.cnblogs.com"); post.addHeader("Referer", "http://passport.cnblogs.com/login.aspx?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F"); String xjson="{'content':'"+message+"','publicFlag':1}"; StringEntity entity=new StringEntity(xjson,"utf-8"); post.setEntity(entity); HttpResponse respons=client.execute(post); if(respons.getStatusLine().getStatusCode()==200&(EntityUtils.toString(respons.getEntity()).contains(message))) return true; else
return false; //System.out.println(respons.getStatusLine().getStatusCode()); //System.out.println(EntityUtils.toString(respons.getEntity()));
} /*** * 登錄時須要post的對象 * * @return 返回對象集合 * * @author http://www.cnblogs.com/xiaoyi115/ * */
public static List<NameValuePair> getNameValuePairs(){ ArrayList<NameValuePair> nvps=new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("__VIEWSTATE", "/wEPDwUKMTk0MDM4Nzg5MGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFC2Noa1JlbWVtYmVy36jcXkF+JKEwq4mk1eC4ETqcaTA=")); nvps.add(new BasicNameValuePair("__EVENTVALIDATION", "/wEdAAW9J9gK2KAJMjMp9r0ov6f2hI6Xi65hwcQ8/QoQCF8JIahXufbhIqPmwKf992GTkd0wq1PKp6+/1yNGng6H71Uxop4oRunf14dz2Zt2+QKDEEdfo2FEmOcxajQv/HKJB0yp2y8y")); nvps.add(new BasicNameValuePair("tbUserName", "瀟一115")); nvps.add(new BasicNameValuePair("tbPassword", "*******")); nvps.add(new BasicNameValuePair("btnLogin", "登 錄")); nvps.add(new BasicNameValuePair("txtReturnUrl", "http://www.cnblogs.com/")); return nvps; } /*** * 獲得登錄後的cookie * @return 返回cookies * * @author http://www.cnblogs.com/xiaoyi115/ * */
public static List<Cookie> getCookies( List<NameValuePair> nvp,String uri) throws ClientProtocolException, IOException{ DefaultHttpClient client=new DefaultHttpClient(); HttpPost post=new HttpPost(uri); post.addHeader("Accept-Encoding", "gzip,deflate,sdch"); post.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6"); post.addHeader("Content-Type", "application/x-www-form-urlencoded"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36"); post.addHeader("Origin", "http://passport.cnblogs.com"); post.addHeader("Referer", "http://passport.cnblogs.com/login.aspx?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F"); post.setEntity(new UrlEncodedFormEntity(nvp,HTTP.UTF_8)); client.execute(post); List<Cookie> cookies=client.getCookieStore().getCookies(); return cookies; }
另外,對於爬蟲來講,對網頁的分析也是一件很是重要的事情。推薦開源工具htmlparser.cookie
新浪微博的登錄會比博客園的登錄稍微難一些。新浪微博會有一步預登錄,獲取到一些信息,利用這些信息再進行登錄。多線程
固然,項目中的爬蟲遠比這個要複雜。須要多線程,既然用到了多線程,就要對線程進行管理、通訊,牽扯多個線程如何配合的問題。另外爬取策略也須要考慮,通常爬取在大的方面會有深度優先和廣度優先。固然,不是簡單的深度或廣度,通常須要進行優化,和中止策略。對於同一個站點,不能過於頻繁的爬取,這樣很容易被禁IP。app
爬蟲須要瞭解的東西還不少。就扯這麼多吧。工具
版權全部,歡迎轉載,可是轉載請註明出處:瀟一