PHP中怎樣實現文章采集

  數據采集,大部分是用正則表達式,我簡單地介紹下如何實現采集的思路.這裡說的是php的實現.一般是本機運行,放到空間上是不明智的,因為不但很耗資源還需要支持遠程抓取函數,比如file_get_contents($urls)file($url)等.

  1,文章列表頁面的自動切換,以及文章路徑的獲得.

  2,獲得:標題,內容

  3,入庫

  4,問題

  1,文章列表頁面的自動切換,以及文章路徑的獲得.

  a,列表頁面的自動切換一般依賴動態頁面來實現.比如

  https://www.phpfirst.com/foru … d=1&page=$i

  可以在後面利用$i的自動增加或范圍來實現,比如$i++;

  也可以像penzi演示的那個一樣,要從第幾頁到第幾頁,代碼方面控制$i的范圍就可以.

  b,文章路徑的獲得分需要填正則和無需填正則2種:

  1)無需填正則就是獲得上面的文章列表頁面的所有連接

  但是最好對連接進行過濾,處理—判斷重復連接,隻留一個,處理相對路徑,變成絕對路徑.比如../ 和./等.

  以下是我寫的亂七八糟的實現函數:

  PHP:

  ——————————————————————————–

  

  //$e=clinchgeturl("https://phpfirst.com/forumdisplay.php?fid=1");

  //var_dump($e);

  function clinchgeturl($url)

  {

  //$url="https://127.0.0.1/1.htm";

  //$rootpath="https://fsrootpathfsfsf/yyyyyy/";

  //var_dump($rrr);

  if(eregi((.)*[.](.)*,$url)){

  $roopath=split("/",$url);

  $rootpath="https://".$roopath[2]."/";

  $nnn=count($roopath)-1;for($yu=3;$yu<$nnn;$yu++){$rootpath.=$roopath[$yu]."/";}

  // var_dump($rootpath); //http: ,,127.0.0.1,xnml,index.php

  }

  else{$rootpath=$url; //var_dump($rootpath);

  }

  if(isset($url)){

  echo "$url 有下列褳接:
";

  $fcontents = file($url);

  while(list(,$line)=each($fcontents)){

  while(eregi((href[[:space:]]*=[[:space:]]*"?[[:alnum:]:@/._-]+[?]?[^"]*"?),$line,$regs)){

  //$regs[1] = eregi_replace((href[[:space:]]*=[[:space:]]*"?)([[:alnum:]:@/._-]+)("?),"\2",$regs[1]);

  $regs[1] = eregi_replace((href[[:space:]]*=[[:space:]]*["]?)([[:alnum:]:@/._-]+[?]?[^"]*)(.*)[^"/]*(["]?),"\2",$regs[1]);

  if(!eregi(^https://,$regs[1])){

  if(eregi(^..,$regs[1])){

  // $roopath=eregi_replace((https://)?([[:alnum:]:@/._-]+)[[:alnum:]+](.*)[[:alnum:]+],"https://\2",$url);

  $roopath=split("/",$rootpath);

  $rootpath="https://".$roopath[2]."/";

  //echo "這是根本d :"."
";

  $nnn=count($roopath)-1;for($yu=3;$yu<$nnn;$yu++){$rootpath.=$roopath[$yu]."/";}

  //var_dump($rootpath);

  if(eregi(^..[/[:alnum:]],$regs[1])){

  //echo "這是../目錄/ :"."
";

  //$regs[1]="../xx/xxxxxx.xx";

  // $rr=split("/",$regs[1]);

  //for($oooi=1;$oooi

  $rrr=$regs[1];

  // {$rrr.="/".$rr[$oooi];

  $rrr = eregi_replace("^[.][.][/]",,$rrr); //}

  $regs[1]=$rootpath.$rrr;

  }

  }else{

  if(eregi(^[[:alnum:]],$regs[1])){ $regs[1]=$rootpath.$regs[1]; }

  else{ $regs[1] = eregi_replace("^[/]",,$regs[1]); $regs[1]=$rootpath.$regs[1]; }

  }

  }

  $line = $regs[2];

  if(eregi((.)*[.](htm|shtm|html|asp|aspx|php|jsp|cgi)(.)*,$regs[1])){

  $out[0][]=$regs[1]; }

  }

  }

  }for ($ouou=0;$ouou

  {

  if($out[0][$ouou]==$out[0][$ouou+1]){

  $sameurlsum=1;

  //echo "sameurlsum=1:";

  for($sameurl=1;$sameurl

  if($out[0][$ouou+$sameurl]==$out[0][$ouou+$sameurl+1]){$sameurlsum++;}

  else{break;}

  }

  for($p=$ouou;$p

  { $out[0][$p]=$out[0][$p+$sameurlsum];}

  }

  }

  $i=0;

  while($out[0][++$i]) {

  //echo $root.$out[0][$i]."
";

  $outed[0][$i]=$out[0][$i];

  }

  unset($out);

  $out=$outed; return $out;

  }

  ?>

  上面的東西隻能zend,不然有礙市容:(

  得到所有唯一的連接後,放到數組

  2)需要填正則的處理

  如果要準確地獲得需要的文章連接,就用這個辦法

  按照ketle的思路

  用

  PHP:

  ——————————————————————————–

  function cut($file,$from,$end){

  $message=explode($from,$file);

  $message=explode($end,$message[1]);

  return $message[0];

  }

  $from是列表前面的html代碼

  $end是列表後面的html代碼

  以上可以通過表單提交參數.

  對列表頁面不是列表的部分去除,剩下的是需要的連接,

  隻要再通過下面正則得到:

  PHP:

  ——————————————————————————–

  preg_match("/^(https://)?(.*)/i",

  $url, $matches);

  return $matches[2];

  2,獲得:標題,內容

  a首先,利用得到的文章路徑,讀取目標路徑

  可以通過以下函數:

  PHP:

  ——————————————————————————–

  function getcontent($url) {

  if($handle = fopen ($url, "rb")){

  $contents = "";

  do {

  $data = fread($handle, 2048);

  if (strlen($data) == 0) {

  break;

  }

  $contents .= $data;

  } while(true);

  fclose ($handle);

  }

  else

  exit("……..");

  return $contents;

  }

  或者直接

  PHP:

  ——————————————————————————–

  file_get_contents($urls);

  後者比較方便,但是缺點對比上面的就知道.

  b,接下來得到標題:

  一般用這個實現:

  PHP:

  ——————————————————————————–

  preg_match("||",$allcontent,$title);

  裡面的部分通過提交表單得到.

  也可以通過一系列的cut函數

  比如上面提過的function cut($file,$from,$end),具體的字符串切割可以通過字符處理函數切割實現,後面"取得內容"詳細講.

  c,取得內容

  取得內容方面和取得標題思路一樣但情況比較復雜,因為內容附近不會是這麼簡單.

  1)內容附近的特征字符串有雙引號,空格,換行符號等是大障礙

  雙引號需要變成 "  可以通過addslashes()處理

  換行符號要去掉 可以通過

  PHP:

  ——————————————————————————–

  $a=ereg_replace("
", , $a);

  $a=ereg_replace("", , $a);

  去掉.

  2)思路2,利用一大堆切割相關的函數對內容提取,需要大量的實踐,調試,我正在弄這裡,沒有獲得什麼突破~~~~~~~~

  3,入庫

  a,切保你的伺服器可以插入

  比如我的可以這樣直接插入:

  PHP:

  ——————————————————————————–

  $sql="INSERT INTO $articles VALUES (, $title, , $article,, , clinch, from, 關鍵詞, 1, $欄目id, $time, 1);

";

  其中

  PHP:

  ——————————————————————————–

  (,

  是自動升序的

發佈留言