58爬蟲了百姓,趕集和58互爬,最后各種信息相同,都是爬蟲后的數據庫調用,潛規則啊,幾家獨大還暗中各種攻擊,趕驢網的幽默事例我不想多評價。這個時代是砸.錢*養.錢的時代,各種姚晨楊冪葛優,各種地鐵公車廣告,各種衛視廣告,鋪天蓋地~~~
來談php爬蟲抓取信息~~ php爬蟲首推Curl函數了,先來認識下它。
0x01.curl擴展的安裝:
1.確保php子文件夾ext里面有php_curl.dll(一般都有的,一般配置時候會設置html' target='_blank'>環境變量的)
2.將php.ini里面的;extension=php_curl.dll反注釋為extension=php_curl.dll
3.重啟apache完了。
4.如果還不行,把php5/libeay32.dll,ssleay32.dll復制到系統目錄windows/下,這2個dll的描述是OpenSSL Shared Library。
否則會出現
Fatal error: Call to undefined function curl_init() in XX:XXXXXX.php on line 3?
這樣未定義,找不到庫的錯誤,大家懂的。
0x02.先來熟悉下curl再去采集抓取,信息時代,大爆炸,爬蟲個信息不是難事。順便測試登陸,COOKIE。PHP中的CURL函數庫(Client URL Library Function)是個強大的庫。
curl_close — 關閉一個curl會話
curl_copy_handle — 拷貝一個curl連接資源的所有內容和參數
curl_errno — 返回一個包含當前會話錯誤信息的數字編號
curl_error — 返回一個包含當前會話錯誤信息的字符串
curl_exec — 執行一個curl會話
curl_getinfo — 獲取一個curl連接資源句柄的信息
curl_init — 初始化一個curl會話
curl_multi_add_handle — 向curl批處理會話中添加單獨的curl句柄資源
curl_multi_close — 關閉一個批處理句柄資源
curl_multi_exec — 解析一個curl批處理句柄
curl_multi_getcontent — 返回獲取的輸出的文本流
curl_multi_info_read — 獲取當前解析的curl的相關傳輸信息
curl_multi_init — 初始化一個curl批處理句柄資源
curl_multi_remove_handle — 移除curl批處理句柄資源中的某個句柄資源
curl_multi_select — Get all the sockets associated with the cURL extension, which can then be "selected"
curl_setopt_array — 以數組的形式為一個curl設置會話參數
curl_setopt — 為一個curl設置會話參數
curl_version — 獲取curl相關的版本信息
curl_init()函數的作用初始化一個curl會話,curl_init()函數唯一的一個參數是可選的,表示一個url地址。
curl_exec()函數的作用是執行一個curl會話,唯一的參數是curl_init()函數返回的句柄。
curl_close()函數的作用是關閉一個curl會話,唯一的參數是curl_init()函數返回的句柄。
簡單實例:
<?php
$url = "http://yxmhero1989.blog.163.com/";//不建議爬大型網站,一般都有反爬蟲機制,被封了IP別怪我~~
$ch = curl_init($url);//初始curl會話
$fp = fopen("homepage.txt", "w");//這里是把抓取的網頁內容寫入一個txt文件,下面會告訴你操作數據庫。
curl_setopt($ch, CURLOPT_FILE, $fp);//為一個curl設置會話參數
curl_setopt($ch, CURLOPT_HEADER, 0);//設置header
curl_exec($ch);//執行curl會話
curl_close($ch);//關閉curl會話
fclose($fp);
?>
0x03.關于CURL_SETOPT()函數的設置
bool curl_setopt (int ch, string option, mixed value)
curl_setopt()函數將為一個CURL會話設置選項。option參數是你想要的設置,value是這個選項給定的值。
下列選項的值將被作為長整形使用(在option參數中指定):
* CURLOPT_INFILESIZE: 當你上傳一個文件到遠程站點,這個選項告訴PHP你上傳文件的大小。
* CURLOPT_VERBOSE: 如果你想CURL報告每一件意外的事情,設置這個選項為一個非零值。
* CURLOPT_HEADER: 如果你想把一個頭包含在輸出中,設置這個選項為一個非零值。
* CURLOPT_NOPROGRESS: 如果你不會PHP為CURL傳輸顯示一個進程條,設置這個選項為一個非零值。注意:PHP自動設置這個選項為非零值,你應該僅僅為了調試的目的來改變這個選項。
* CURLOPT_NOBODY: 如果你不想在輸出中包含body部分,設置這個選項為一個非零值。
* CURLOPT_FAILONERROR: 如果你想讓PHP在發生錯誤(HTTP代碼返回大于等于300)時,不顯示,設置這個選項為一人非零值。默認行為是返回一個正常頁,忽略代碼。
* CURLOPT_UPLOAD: 如果你想讓PHP為上傳做準備,設置這個選項為一個非零值。
* CURLOPT_POST: 如果你想PHP去做一個正規的HTTP POST,設置這個選項為一個非零值。這個POST是普通的 application/x-www-from-urlencoded 類型,多數被HTML表單使用。
* CURLOPT_FTPLISTONLY: 設置這個選項為非零值,PHP將列出FTP的目錄名列表。
* CURLOPT_FTPAPPEND: 設置這個選項為一個非零值,PHP將應用遠程文件代替覆蓋它。
* CURLOPT_NETRC: 設置這個選項為一個非零值,PHP將在你的 ~./netrc 文件中查找你要建立連接的遠程站點的用戶名及密碼。
* CURLOPT_FOLLOWLOCATION: 設置這個選項為一個非零值(象 “Location: “)的頭,服務器會把它當做HTTP頭的一部分發送(注意這是遞歸的,PHP將發送形如 “Location: “的頭)。
* CURLOPT_PUT: 設置這個選項為一個非零值去用HTTP上傳一個文件。要上傳這個文件必須設置CURLOPT_INFILE和CURLOPT_INFILESIZE選項.
* CURLOPT_MUTE: 設置這個選項為一個非零值,PHP對于CURL函數將完全沉默。
* CURLOPT_TIMEOUT: 設置一個長整形數,作為最大延續多少秒。
* CURLOPT_LOW_SPEED_LIMIT: 設置一個長整形數,控制傳送多少字節。
* CURLOPT_LOW_SPEED_TIME: 設置一個長整形數,控制多少秒傳送CURLOPT_LOW_SPEED_LIMIT規定的字節數。
* CURLOPT_RESUME_FROM: 傳遞一個包含字節偏移地址的長整形參數,(你想轉移到的開始表單)。
* CURLOPT_SSLVERSION: 傳遞一個包含SSL版本的長參數。默認PHP將被它自己努力的確定,在更多的安全中你必須手工設置。
* CURLOPT_TIMECONDITION: 傳遞一個長參數,指定怎么處理CURLOPT_TIMEVALUE參數。你可以設置這個參數為TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。這僅用于HTTP。
* CURLOPT_TIMEVALUE: 傳遞一個從1970-1-1開始到現在的秒數。這個時間將被CURLOPT_TIMEVALUE選項作為指定值使用,或被默認TIMECOND_IFMODSINCE使用。
下列選項的值將被作為字符串:
* CURLOPT_URL: 這是你想用PHP取回的URL地址。你也可以在用curl_init()函數初始化時設置這個選項。
* CURLOPT_USERPWD: 傳遞一個形如[username]:[password]風格的字符串,作用PHP去連接。
* CURLOPT_PROXYUSERPWD: 傳遞一個形如[username]:[password] 格式的字符串去連接HTTP代理。
* CURLOPT_RANGE: 傳遞一個你想指定的范圍。它應該是”X-Y”格式,X或Y是被除外的。HTTP傳送同樣支持幾個間隔,用逗句來分隔(X-Y,N-M)。
* CURLOPT_POSTFIELDS: 傳遞一個作為HTTP “POST”操作的所有數據的字符串。
* CURLOPT_REFERER: 在HTTP請求中包含一個”referer”頭的字符串。
* CURLOPT_USERAGENT: 在HTTP請求中包含一個”user-agent”頭的字符串。
* CURLOPT_FTPPORT: 傳遞一個包含被ftp “POST”指令使用的IP地址。這個POST指令告訴遠程服務器去連接我們指定的IP地址。這個字符串可以是一個IP地址,一個主機名,一個網絡界面名 (在UNIX下),或是‘-’(使用系統默認IP地址)。
* CURLOPT_COOKIE: 傳遞一個包含HTTP cookie的頭連接。
* CURLOPT_SSLCERT: 傳遞一個包含PEM格式證書的字符串。
* CURLOPT_SSLCERTPASSWD: 傳遞一個包含使用CURLOPT_SSLCERT證書必需的密碼。
* CURLOPT_COOKIEFILE: 傳遞一個包含cookie數據的文件的名字的字符串。這個cookie文件可以是Netscape格式,或是堆存在文件中的HTTP風格的頭。
* CURLOPT_CUSTOMREQUEST: 當進行HTTP請求時,傳遞一個字符被GET或HEAD使用。為進行DELETE或其它操作是有益的,更Pass a string to be used instead of GET or HEAD when doing an HTTP request. This is useful for doing or another, more obscure, HTTP request. 注意: 在確認你的服務器支持命令先不要去這樣做。下列的選項要求一個文件描述(通過使用fopen()函數獲得):
* CURLOPT_FILE: 這個文件將是你放置傳送的輸出文件,默認是STDOUT.
* CURLOPT_INFILE: 這個文件是你傳送過來的輸入文件。
* CURLOPT_WRITEHEADER: 這個文件寫有你輸出的頭部分。
* CURLOPT_STDERR: 這個文件寫有錯誤而不是stderr。用來獲取需要登錄的頁面的例子,當前做法是每次或許都登錄一次,有需要的人再做改進了.
PHP實現最簡單爬蟲原型(話說原作者的正則注釋反了,出現錯誤哈哈)
代碼如下 <?php
function _getUrlContent($url){
$handle = fopen($url, "r");
if($handle){
$content = stream_get_contents($handle,1024*1024);
return $content;
}else{
return false;
}
}
function _filterUrl($web_content){
$reg_tag_a = "/<[a|A].*?href=['"]{0,1}([^>'" ]*).*?>/";
//$result = preg_match_all($reg_tag_a,$web_content,$match_result);
$result = preg_match_all("/<meta[^>]*?name=['"]?description['"]?[^>]*?>/is",$web_content,$match_result);
if($result){
return $match_result[1];
}
}
function _reviseUrl($base_url,$url_list){
$url_info = parse_url($base_url);
$base_url = $url_info["scheme"].'://';
if($url_info["user"]&&$url_info["pass"]){
$base_url .= $url_info["user"].":".$url_info["pass"]."@";
}
$base_url .= $url_info["host"];
if($url_info["port"]){
$base_url .= ":".$url_info["port"];
}
$base_url .= $url_info["path"];
print_r($base_url);
if(is_array($url_list)){
foreach ($url_list as $url_item) {
if(preg_match('/^http/',$url_item)){
//已經是完整的url
$result[] = $url_item;
}else {
//不完整的url
$real_url = $base_url.'/'.$url_item;
$result[] = $real_url;
}
}
return $result;
}else {
return;
}
}
function crawler($url){
$content = _getUrlContent($url);
if($content){
$url_list = _reviseUrl($url,_filterUrl($content));
if($url_list){
return $url_list;
}else {
return ;
}
}else{
return ;
}
}
function main(){
$current_url = "http://hao123.com/";//初始url
$fp_puts = fopen("url.txt","ab");//記錄url列表
$fp_gets = fopen("url.txt","r");//保存url列表
do{
$result_url_arr = crawler($current_url);
if($result_url_arr){
foreach ($result_url_arr as $url) {
fputs($fp_puts,$url."/r/n");
}
}
}while ($current_url = fgets($fp_gets,1024));//不斷獲得url
}
main();
?>
<input type="text" value="關鍵字" />
<input type="submit" value="搜索"/>
代碼如下<?phpclass CurlComponent{var $headers;var $user_agent;var $compression;var $cookie_file;var $proxy;functionset_value($cookies=TRUE,$cookie='cookies.txt',$compression='gzip',$proxy='') {$this->headers[] = "Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg";$this->headers[] = "Connection: Keep-Alive";$this->headers[] = "Content-type: application/x-www-form-urlencoded";$this->user_agent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)";$this->compression=$compression;$this->proxy=$proxy;$this->cookies=$cookies;if ($this->cookies == TRUE) $this->cookie($cookie);}function cookie($cookie_file) {if (file_exists($cookie_file)) {$this->cookie_file=$cookie_file;} else {@fopen($cookie_file,'w')or$this->error("The cookie file could not be opened. Make sure this directory has the correct permissions");$this->cookie_file=$cookie_file;@fclose($cookie_file);}}function get($url,$refer='') {$process =curl_init($url);curl_setopt($process,CURLOPT_REFERER, $refer);curl_setopt($process,CURLOPT_HTTPHEADER, $this->headers);curl_setopt($process,CURLOPT_USERAGENT, $this->user_agent);if ($this->cookies == TRUE)curl_setopt($process,CURLOPT_COOKIEFILE, $this->cookie_file);if ($this->cookies == TRUE)curl_setopt($process,CURLOPT_COOKIEJAR, $this->cookie_file);curl_setopt($process,CURLOPT_ENCODING, $this->compression);curl_setopt($process,CURLOPT_TIMEOUT, 30000);if ($this->proxy)curl_setopt($cUrl,CURLOPT_PROXY, 'proxy_ip:proxy_port');curl_setopt($process,CURLOPT_RETURNTRANSFER, 1);$return =curl_exec($process);curl_close($process);return $return;}function post($url,$data,$refer) {$process =curl_init($url);curl_setopt($process,CURLOPT_REFERER, $refer);curl_setopt($process,CURLOPT_HTTPHEADER, $this->headers);curl_setopt($process,CURLOPT_USERAGENT, $this->user_agent);if ($this->cookies == TRUE)curl_setopt($process,CURLOPT_COOKIEFILE, $this->cookie_file);if ($this->cookies == TRUE)curl_setopt($process,CURLOPT_COOKIEJAR, $this->cookie_file);curl_setopt($process,CURLOPT_ENCODING, $this->compression);curl_setopt($process,CURLOPT_TIMEOUT, 30000);if ($this->proxy)curl_setopt($cUrl,CURLOPT_PROXY, 'proxy_ip:proxy_port');curl_setopt($process,CURLOPT_POSTFIELDS, $data);curl_setopt($process,CURLOPT_RETURNTRANSFER, 1);curl_setopt($process,CURLOPT_FOLLOWLOCATION, 1);curl_setopt($process,CURLOPT_POST, 1);$return =curl_exec($process);curl_close($process);return $return;}function error($error) {echo "<center><div style='width:500px;border: 3px solid #FFEEFF; padding: 3px; background-color: #FFDDFF;font-family: verdana; font-size: 10px'><b>cURL Error</b><br>$error</div></center>";die;}}?>
0x04.POST數據
代碼如下﹤?php$phoneNumber = '13812345678';$message = 'This message was generated by curl and php';$curlPost = 'pNUMBER=' . urlencode($phoneNumber) . '&MESSAGE=' . urlencode($message) . '&SUBMIT=Send';$ch = curl_init();curl_setopt($ch, CURLOPT_URL, 'http://www.lxvoip.com/sendSMS.php');curl_setopt($ch, CURLOPT_HEADER, 1);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);$data = curl_exec();curl_close($ch);?﹥
0x05.模擬登錄
Curl 模擬登錄 discuz 程序,適合DZ7.0,將username改成你的用戶名,userpass改成你的密碼就可以了.
代碼如下<?php !extension_loaded('curl') && die('The curl extension is not loaded.');$discuz_url = 'http://www.lxvoip.com';//論壇地址 $login_url = $discuz_url .'/logging.php?action=login';//登錄頁地址 $get_url = $discuz_url .'/my.php?item=threads'; //我的帖子 $post_fields = array();//以下兩項不需要修改 $post_fields['loginfield'] = 'username';$post_fields['loginsubmit'] = 'true';//用戶名和密碼,必須填寫 $post_fields['username'] = 'lxvoip';$post_fields['password'] = '88888888';//安全提問 $post_fields['questionid'] = 0;$post_fields['answer'] = '';//@todo驗證碼 $post_fields['seccodeverify'] = '';//獲取表單FORMHASH $ch = curl_init($login_url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);$contents = curl_exec($ch);curl_close($ch);preg_match('/<inputs*type="hidden"s*name="formhash"s*value="(.*?)"s*/>/i', $contents,$matches);if(!empty($matches)) {$formhash = $matches[1];} else {die('Not found the forumhash.');}//POST數據,獲取COOKIE $cookie_file = dirname(__FILE__) . '/cookie.txt';//$cookie_file = tempnam('/tmp'); $ch = curl_init($login_url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);curl_exec($ch);curl_close($ch);//帶著上面得到的COOKIE獲取需要登錄后才能查看的頁面內容 $ch = curl_init($get_url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);$contents = curl_exec($ch);curl_close($ch);var_dump($contents);?> 再看幾個模擬登錄的例子:
代碼如下 <?php
error_reporting(E_ALL);
$login_url = '192.168.18.25/test/php-curl-login.php';//模擬登錄地址
$cookie_url='192.168.18.25/test/php-curl-cookie.php'; //模擬發帖
$post_fields = array();
$post_fields['user_name'] = 'phpcto';
$post_fields['pass_word'] = 'phpcto123';
$cookie_file =tempnam('./temp','cookie');
ob_start();
echo '<pre>';
$ch = curl_init($login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);// 返回頁面內容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); //獲取的信息以文件流的形式返回
curl_setopt($ch, CURLOPT_POST, 1);// 提交post數據
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);// 保存cookie
curl_exec($ch); // 執行
curl_close($ch);// 關閉
echo '<hr/>';
$ch4=curl_init($cookie_url);
curl_setopt($ch4, CURLOPT_COOKIEFILE, $cookie_file); // 使用cookie
curl_exec($ch4);
curl_close($ch4);
echo '<hr/>';
echo '</pre>';
ob_end_flush();
代碼如下 php 使用curl模擬登錄discuz以及模擬發帖
<?php
$discuz_url = 'http://127.0.0.1/discuz/';//論壇地址
$login_url = $discuz_url .'logging.php?action=login';//登錄頁地址
$post_fields = array();
//以下兩項不需要修改
$post_fields['loginfield'] = 'username';
$post_fields['loginsubmit'] = 'true';
//用戶名和密碼,必須填寫
$post_fields['username'] = 'tianxin';
$post_fields['password'] = '111111';
//安全提問
$post_fields['questionid'] = 0;
$post_fields['answer'] = '';
//@todo驗證碼
$post_fields['seccodeverify'] = '';
//獲取表單FORMHASH
$ch = curl_init($login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$contents = curl_exec($ch);
curl_close($ch);
preg_match('/<inputs*type="hidden"s*name="formhash"s*value="(.*?)"s*/>/i', $contents, $matches);
if(!empty($matches)) {
$formhash = $matches[1];
} else {
die('Not found the forumhash.');
}
//POST數據,獲取COOKIE,cookie文件放在網站的temp目錄下
$cookie_file = tempnam('./temp','cookie');
$ch = curl_init($login_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_exec($ch);
curl_close($ch);
//取到了關鍵的cookie文件就可以帶著cookie文件去模擬發帖,fid為論壇的欄目ID
$send_url = $discuz_url."post.php?action=newthread&fid=2";
$ch = curl_init($send_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
$contents = curl_exec($ch);
curl_close($ch);
//這里的hash碼和登陸窗口的hash碼的正則不太一樣,這里的hidden多了一個id屬性
preg_match('/<inputs*type="hidden"s*name="formhash"s*id="formhash"s*value="(.*?)"s*/>/i', $contents, $matches);
if(!empty($matches)) {
$formhash = $matches[1];
} else {
die('Not found the forumhash.');
}
$post_data = array();
//帖子標題
$post_data['subject'] = 'test2';
//帖子內容
$post_data['message'] = 'test2';
$post_data['topicsubmit'] = "yes";
$post_data['extra'] = '';
//帖子標簽
$post_data['tags'] = 'test';
//帖子的hash碼,這個非常關鍵!假如缺少這個hash碼,discuz會警告你來路的頁面不正確
$post_data['formhash']=$formhash;
$ch = curl_init($send_url);
curl_setopt($ch, CURLOPT_REFERER, $send_url); //偽裝REFERER
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$contents = curl_exec($ch);
curl_close($ch);
//清理cookie文件
unlink($cookie_file);
?>
代碼如下 <?php
$cookie_file = dirname(__FILE__)."/cookie_".md5(basename(__FILE__)).".txt"; // 設置Cookie文件保存路徑及文件名
function vlogin($url,$data){ // 模擬登錄獲取Cookie函數
$curl = curl_init(); // 啟動一個CURL會話
curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 對認證證書來源的檢查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 從證書中檢查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模擬用戶使用的瀏覽器
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自動跳轉
curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自動設置Referer
curl_setopt($curl, CURLOPT_POST, 1); // 發送一個常規的Post請求
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post 提交的數據包
curl_setopt($curl, CURLOPT_COOKIEJAR, $GLOBALS['cookie_file']); // 存放 Cookie信息的文件名稱
curl_setopt($curl, CURLOPT_COOKIEFILE, $GLOBALS['cookie_file']); // 讀取上面所儲存的Cookie信息
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環
curl_setopt($curl, CURLOPT_HEADER, 0); // 顯示返回的Header區域內容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 獲取的信息以文件流的形式返回
$tmpInfo = curl_exec($curl); // 執行操作
if (curl_errno($curl)) {
echo 'Errno'.curl_error($curl);
}
curl_close($curl); // 關閉 CURL會話
return $tmpInfo; // 返回數據
}
function vget($url){ // 模擬獲取內容函數
$curl = curl_init(); // 啟動一個CURL會話
curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 對認證證書來源的檢查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 從證書中檢查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模擬用戶使用的瀏覽器
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自動跳轉
curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自動設置Referer
curl_setopt($curl, CURLOPT_HTTPGET, 1); // 發送一個常規的Post請求
curl_setopt($curl, CURLOPT_COOKIEFILE, $GLOBALS['cookie_file']); // 讀取上面所儲存的Cookie信息
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環
curl_setopt($curl, CURLOPT_HEADER, 0); // 顯示返回的Header區域內容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 獲取的信息以文件流的形式返回
$tmpInfo = curl_exec($curl); // 執行操作
if (curl_errno($curl)) {
echo 'Errno'.curl_error($curl);
}
curl_close($curl); // 關閉 CURL會話
return $tmpInfo; // 返回數據
}
function vpost($url,$data){ // 模擬提交數據函數
$curl = curl_init(); // 啟動一個CURL會話
curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 對認證證書來源的檢查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 從證書中檢查SSL加密算法是否存在
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模擬用戶使用的瀏覽器
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自動跳轉
curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自動設置Referer
curl_setopt($curl, CURLOPT_POST, 1); // 發送一個常規的Post請求
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post 提交的數據包
curl_setopt($curl, CURLOPT_COOKIEFILE, $GLOBALS['cookie_file']); // 讀取上面所儲存的Cookie信息
curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環
curl_setopt($curl, CURLOPT_HEADER, 0); // 顯示返回的Header區域內容
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 獲取的信息以文件流的形式返回
$tmpInfo = curl_exec($curl); // 執行操作
if (curl_errno($curl)) {
echo 'Errno'.curl_error($curl);
}
curl_close($curl); // 關鍵 CURL會話
return $tmpInfo; // 返回數據
}
function delcookie($cookie_file){ // 刪除 Cookie函數
@unlink($cookie_file); // 執行刪除
}
// 使用實例
// vlogin('192.168.18.25/test/login.php','user_name=yang&pass_word=yangjs123'); // 登錄獲取 Cookie
//echo vget('192.168.18.25/test/login.php');
echo vpost('192.168.18.25/test/login.php','user_name=yang&pass_word=yangjs123');
?>
0x06.PHP多線程抓取網頁實現代碼代碼如下 <?php
$ch3 = curl_init();
$ch4 = curl_init();
curl_setopt($ch3, CURLOPT_URL, "http://www.XX.com/");
curl_setopt($ch3, CURLOPT_HEADER, 0);
curl_setopt($ch4, CURLOPT_URL, "http://www.00.com/");
curl_setopt($ch4, CURLOPT_HEADER, 0);
$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch3);
curl_multi_add_handle($mh,$ch4);
do{
curl_multi_exec($mh,$flag);
}while($flag > 0);
curl_multi_remove_handle($mh,$ch3);
curl_multi_remove_handle($mh,$ch4);
curl_multi_close($mh);
?>
0x07.抓取和分析一個文件是非常簡單的事。file函數也可以,不同的網站要寫不同的正則表達式來匹配抓取想要的內容。
以下實現php抓取網頁title,keywords,description,content,注釋掉的數據庫操作(即把抓取的內容存到數據庫)
代碼如下 <?php
header('Content-Type: text/html; charset=gbk');
$url ="http://www.jj59.com/qingganwenzhang/093750.html";
$lines_array=file($url);//read entire web file into array
//var_dump($lines_array);
$lines_string = implode('', $lines_array);//maybe not in a row,so join the array elements with a string
$count=count($lines_string);
for($i=0;$i<$count;$i++){
if(preg_match("/<title>(.*)</title>/is",$lines_string,$title)){//標題
$title=$title[0];
}
if(preg_match("/<meta[^>]*?name=['"]?keywords['"]?[^>]*?>/is",$lines_string,$keywords)){//關鍵字
$title2=$keywords[0];
}
if(preg_match("/<meta[^>]*?name=['"]?description['"]?[^>]*?>/is",$lines_string,$description)){//描述
$title3=$description[0];
}
if(preg_match("/<div class="content"><div id=zt><div id="twgg" class="gg"></div>(.*)<p>(.*)</p>(.*)<p class="bianji">/is",$lines_string,$content)){//描述
$title4=$content[0];
//var_dump($title4);
}
}
$title=substr($title,7,-19);
$title2=substr($title2,31,-4);
$title3=substr($title3,34,-4);
//$title4=substr($title4,34,-40);
echo "Title:".$title."<br>";
echo "KeyWords:".$title2."<br>";
echo "Description:".$title3."<br>";
echo "Content:".$title4."<br>";
//$query="insert into insun4 values('$i','$title','$title2','$title3','$title4')";
//$result=mysql_query($query) or die("查詢數據失敗");//執行查詢
?>
代碼如下
<?php
header('Content-Type: text/html; charset=gbk');
error_reporting(E_CORE_ERROR);
$url ="http://yxmhero1989.blog.163.com";
$lines_array=file($url);//read entire web file into array
//var_dump($lines_array);
$lines_string = implode('', $lines_array);//maybe not in a row,so join the array elements with a string
$count=count($lines_string);
for($i=0;$i<$count;$i++){
//if(preg_match("/<title>(.*)</title>/is",$lines_string,$title)){//標題
if(eregi("<title>(.*)</title>",$lines_string,$title)){
$title=$title[0];
}
if(preg_match("/<meta[^>]*?name=['"]?keywords['"]?[^>]*?>/is",$lines_string,$keywords)){//關鍵字
$title2=$keywords[0];
}
if(preg_match("/<meta[^>]*?name=['"]?description['"]?[^>]*?>/is",$lines_string,$description)){//描述
$title3=$description[0];
}
}
$title=substr($title,7,-19);
$title2=substr($title2,31,-3);
$title3=substr($title3,34,-5);
echo "Title:".$title."<br>";
echo "KeyWords:".$title2."<br>";
echo "Description:".$title3."<br>";
//$query="insert into insun4 values('$i','$title','$title2','$title3')";
//$result=mysql_query($query) or die("查詢數據失敗");//執行查詢
?>
結果:
Title:Minghacker is Insun - InSun
KeyWords:InSun,Minghacker is Insun,網易博客,網易,blog
Description:百度(baidu)分詞算法分析,對網易博客日志標簽功能的期盼,CDbConnection failed to open the DB connection: could not find driver,Warning: date() [function.date]: It is not safe to rely on the system's timezone settings.,淺談Python web框架,谷歌是如何做代碼審查的(Things Everyone Should Do: Code Review),Failed to connect to mailserver at localhost port 25,PHP flock文件鎖,針對$_SERVER[’PHP_SELF’]的跨站腳本攻擊,安全跑路指南與安全跑路指南升級版,InSun的網易博客,凡你醉處 你說過 皆非他鄉,愛好寫詞攝影和美女。專注編程和安全。應該可以發好人卡,可能時機沒到
0x08.找到了的數據存到數據庫,然后CSS+DIV架個前臺,在前臺用分頁調用,代碼就不貼了,直接上圖片:
你看多簡單,前面的幾個大站互爬數據添加到數據庫,然后前臺調用,充實了自己的信息庫,減少了手動的工作量,何其樂啊,可是不知道算不算違反?大概惡意競爭才算,所以反爬蟲機制必須的~~~
0x09.淺談反爬蟲機制:
①?,F在各大搜索網站和行業化以及特別商業化的網站應該都有反爬蟲機制,爬蟲需要偽造Agent信息,而且每次爬信息都要有一定的時間間隔(即加上隨機sleep )。
②。robots.txt是一存放于網站根目錄中的文本文件,用來定義網站上哪些內容可以或不能供網絡爬蟲存取,Yahoo也在網站上說明如何利用robots.txt以避免網站或特定網頁數據不被搜索引擎搜集及索引。
③。如果是爬蟲程序來訪,則user-agent會顯示Googlebot或MSNBot等搜索引擎爬蟲程序名稱,每個搜索引擎都有自己的user-agent,以下分別列出國內主要的爬蟲程序。百度baidu.com—-Baiduspider 谷歌google.com—-Googlebot
雅虎yahoo.com—-Yahoo 有道yodao.com—-YodaoBot
搜搜soso.com—-Sosospider/Sosoimagespider 搜狗sogou.com—-sogou 微軟msn.com—-msnbot
自寫程序,if不是上面就access deny,這樣不失流量,也遏制了對手的肆意爬取信息,減少了對公司的損失。
④。重要的2篇文章 分析了反爬蟲策略。
PHP編程 鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。