follow大神教程——實踐java爬蟲之二

第二篇大神開始抓知乎了,喲喲好順利的樣子。html

最終目標:抓取http://www.cfsn.cn/news/node_4534.htm的新聞標題、連接,並存儲到mysql中。java

如今以模仿爲主,第一階段:抓取以後存儲到txt之中。node

將main中url賦值爲http://www.cfsn.cn/news/node_4534.htm,運行結果是該頁面的源碼,接着應該用正則表達式抓取須要的信息。mysql

該頁面的第一條新聞:web

<a href="content/2014-05/14/content_203870.htm" target="_blank">青島22人因生產有害食品獲刑</a>

回頭看大神原文:正則表達式

正則語句爲question_link.+?href=\"(.+?)\"sql

則抓取結果【最新結果】安全

/question/22221540/answer/22120516ide

正則語句爲question_link.+?>(.+?)<函數

則抓取結果爲第一個標題。

=>()中內容是要抓的部分。

觀察食品安全的網頁源碼,_blank具備特殊性,可見其與其餘超連接區分開。

試一下

正則語句:_blank\">(.+?)<

 public static void main(String[] args) {
  // 定義即將訪問的連接
  String url = "http://www.cfsn.cn/news/node_4534.htm";  
  // 訪問連接並獲取頁面內容
  String result = SendGet(url);
  // 使用正則匹配圖片的src內容
  String imgSrc = RegexString(result, "_blank\">(.+?)<");
  // 打印結果
  System.out.println(imgSrc);
 }

 

運行結果:

青島22人因生產有害食品獲刑

(第一次運行顯示超時異常,坑爹網速不給力吖)

接着要將全部結果存儲到ArrayList中,咱們須要新的正則函數

舊的正則函數:

 static String RegexString(String targetStr, String patternStr) {

  // 定義一個樣式模板,此中使用正則表達式,括號中是要抓的內容

  // 至關於埋好了陷阱匹配的地方就會掉下去

  Pattern pattern = Pattern.compile(patternStr);

  // 定義一個matcher用來作匹配

  Matcher matcher = pattern.matcher(targetStr);

  // 若是找到了

  if (matcher.find()) {

   // 打印出結果

   return matcher.group(1);

  }

  return "Nothing";

 }

新的

static ArrayList<String> RegexString(String targetStr, String patternStr) {

  // 預約義一個ArrayList來存儲結果

  ArrayList<String> results = new ArrayList<String>();  

  // 定義一個樣式模板,此中使用正則表達式,括號中是要抓的內容, 至關於埋好了陷阱匹配的地方就會掉下去 

  Pattern pattern = Pattern.compile(patternStr);

  // 定義一個matcher用來作匹配

  Matcher matcher = pattern.matcher(targetStr);

  // 若是找到了

  boolean isFind = matcher.find();

  // 使用循環將句子裏全部的kelvin找出並替換再將內容加到sb裏  

  while(isFind){

   //添加成功匹配的結果  

   results.add(matcher.group(1));

   // 繼續查找下一個匹配對象  

   isFind=matcher.find();

   

  }

  return results;

 }

還要修改main中imgSrc的類型爲ArrayList<String>

運行結果:

[青島22人因生產有害食品獲刑, 廣西查獲120噸鳳爪豬耳等洋垃圾, 臭豆腐用 【略】

成功抓取到全部標題。

抓連接的正則表達式:

若爲href=\"(.+?)\"  多抓了幾個;

若爲href=\"(.+?)\".+?_blank,結果每次都是Connection time out;

還沒系統研究過正則,有多是\"後面的.+?所致

實際測試正則表達式爲span><a href=\"(.+?)\"運行結果則顯示出要的新聞超連接。

 

下來須要標題和連接,設計一個cfsn類(china food safe net)存儲全部抓取到的對象,

public class Cfsn {
 public String title;  //新聞標題
 public String CfsnUrl ;//網頁連接
 
 //構造方法初始化數據
 public Cfsn(){
  title = "" ;
  CfsnUrl = "" ;
 }
 
 @Override
 public String toString(){
  return "標題:"+title+"\n連接:"+CfsnUrl+"\n";
 }
}

Spider類:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//Spider類來存放一些爬蟲經常使用的函數。
public class Spider {
 static String SendGet(String url) {
  // 定義一個字符串用來存儲網頁內容
  String result = "";
  // 定義一個緩衝字符輸入流
  BufferedReader in = null;
  try {
   // 將string轉成url對象
   URL realUrl = new URL(url);
   // 初始化一個連接到那個url的鏈接
   URLConnection connection = realUrl.openConnection();
   // 開始實際的鏈接
   connection.connect();
   // 初始化 BufferedReader輸入流來讀取URL的響應
   in = new BufferedReader(new InputStreamReader(
     connection.getInputStream(), "UTF-8"));
   // 用來臨時存儲抓取到的每一行的數據
   String line;
   while ((line = in.readLine()) != null) {
    // 遍歷抓取到的每一行並將其存儲到result裏面
    result += line;
   }
  } catch (Exception e) {
   System.out.println("發送GET請求出現異常!" + e);
   e.printStackTrace();
  }
  // 使用finally來關閉輸入流
  finally {
   try {
    if (in != null) {
     in.close();
    }
   } catch (Exception e2) {
    e2.printStackTrace();
   }
  }
  return result;
 }
 static ArrayList<Cfsn> GetCfsn(String content) {
  // 預約義一個ArrayList來存儲結果
  ArrayList<Cfsn> results = new ArrayList<Cfsn>();
  // 用來匹配標題
  Pattern questionPattern = Pattern.compile("_blank\">(.+?)<");
  Matcher questionMatcher = questionPattern.matcher(content);
  // 用來匹配url,也就是問題的連接
  Pattern urlPattern = Pattern.compile("span><a href=\"(.+?)\"");
  Matcher urlMatcher = urlPattern.matcher(content);
  // 標題和連接要均能匹配到
  boolean isFind = questionMatcher.find() && urlMatcher.find();
  while (isFind) {
   // 定義一個食品安全網對象來存儲抓取到的信息
   Cfsn zhuhuTemp = new Cfsn();
   zhuhuTemp.title = questionMatcher.group(1);
   zhuhuTemp.CfsnUrl = "http://www.cfsn.cn/news/" + urlMatcher.group(1);
   // 添加成功匹配的結果
   results.add(zhuhuTemp);
   // 繼續查找下一個匹配對象
   isFind = questionMatcher.find() && urlMatcher.find();
  }
  return results;
 }
}

 

Main類:

import java.util.ArrayList;
public class Main {
 public static void main(String args[]) {
  // 定義即將訪問的連接
  String url = "http://www.cfsn.cn/news/node_4534.htm";
  // 訪問連接並獲取頁面內容
  String content = Spider.SendGet(url);
  // 獲取該頁面的全部的知乎對象
  ArrayList<Cfsn> myCfsn = Spider.GetCfsn(content);
  // 打印結果
  System.out.println(myCfsn);
 }
}

結果:

【普大喜奔啊啊啊】

運行三、4遍都是connection time out,絕望的時候竟然抓取成功了(oschina限定上傳圖片小於200k,能夠鄙視一下麼,QQ截圖400K吖吖吖)

最後再次詛咒一下個人網速,明天follow大神繼續下一步

相關文章
相關標籤/搜索