PHP爬蟲技術知識點總結
在的爬蟲框架很多,比較流行的是基於python,nodejs,java,C#,PHP的的框架,其中又以基於python的爬蟲流行最為廣泛,還有的已經是一套傻瓜式的軟體操作,如八爪魚,火車頭等軟體。
今天我們首先嘗試的是使用PHP實作一個爬蟲程序,首先在不使用爬蟲框架的基礎上實踐也是為了理解爬蟲的原理,然後再利用PHP的lib,框架和擴展進行實踐。
#1.PHP簡單的爬蟲–原型
爬蟲的原理:
#給定原始的url;
#分析鏈接,根據設定的正規表示式取得連結中的內容;
有的會更新原始的url再進行分析鏈接,獲取特定內容,周而復始。
-
將取得的內容保存在資料庫中(mysql)或本機檔案中
#
下面是網路上一個例子,我們列下來然後分析
從##main<span style="margin:0px;padding:0px;max-width:100%;font-size:15px;"></span>
函數開始
<?php/** * 爬虫程序 -- 原型 * 从给定的url获取html内容 * @param string $url * @return string */function _getUrlContent($url) { $handle = fopen($url, "r"); if ($handle) { $content = stream_get_contents($handle, -1); //读取资源流到一个字符串,第二个参数需要读取的最大的字节数。默认是-1(读取全部的缓冲数据) // $content = file_get_contents($url, 1024 * 1024); return $content; } else { return false; } } /** * 从html内容中筛选链接 * @param string $web_content * @return array */function _filterUrl($web_content) { $reg_tag_a = '/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/'; $result = preg_match_all($reg_tag_a, $web_content, $match_result); if ($result) { return $match_result[1]; } } /** * 修正相对路径 * @param string $base_url * @param array $url_list * @return array */function _reviseUrl($base_url, $url_list) { $url_info = parse_url($base_url);//解析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"]; 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; } } /** * 爬虫 * @param string $url * @return array */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() { $file_path = "url-01.txt"; $current_url = "http://www.baidu.com/"; //初始url if(file_exists($file_path)){ unlink($file_path); } $fp_puts = fopen($file_path, "ab"); //记录url列表 $fp_gets = fopen($file_path, "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();?>
2.使用crul lib
#Curl是比較成熟的一個lib,異常處理、http header、POST之類都做得很好,重要的是PHP下操作MySQL進行入庫操作比較省心。關於curl的說明具體可以查看PHP官方文檔,不過在多線程Curl(Curl_multi)方面比較麻煩。
開啟crul 針對winow系統:
- php.in中修改(註解;去掉即可)
- php資料夾下的libeay32.dll, ssleay32.dll, libssh2.dll 還有php/ext下的php_curl4個檔案移入windows /system32
步驟: - 使用cURL函數的基本想法是先用curl_init()初始化一個cURL會話; - 接著你可以透過curl_setopt()設定你需要的全部選項; 範例 #$ch = curl_init("http://www.example.com/"); $fp = fopen("example_homepage.txt", "w"# );curl_setopt($ch, CURLOPT_FILE, $fp);curl_setopt($ch , CURLOPT_HEADER, 0);curl_exec($ch);curl_close($ch);fclose($fp);?> 要对https支持,需要在 结果疑惑: 还有我们获得url数据可能会有重复的,这部分处理在我的github上,对应demo2-01.php,或者demo2-02.php stream_get_contents — 读取资源流到一个字符串 $content# = stream_get_contents($handle #, -1); //讀取資源流到一個字串,第二個參數需要讀取的最大的位元組數。預設是-1(讀取全部的緩衝資料) file_get_contents — 将整个文件读入一个字符串
- 然後使用curl_exec()來執行會話;
- 執行完會話後使用curl_close()關閉會話。
一个完整点的例子:<?php/** * 将demo1-01换成curl爬虫 * 爬虫程序 -- 原型 * 从给定的url获取html内容 * @param string $url * @return string */function _getUrlContent($url) { $ch=curl_init(); //初始化一个cURL会话 /*curl_setopt 设置一个cURL传输选项*/ //设置需要获取的 URL 地址 curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HEADER,1); // 设置浏览器的特定header curl_setopt($ch, CURLOPT_HTTPHEADER,
array(
"Host: www.baidu.com",
"Connection: keep-alive",
"Accept: text/html,
application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Upgrade-Insecure-Requests: 1",
"DNT:1",
"Accept-Language: zh-CN,zh;q=0.8,en-GB;q=0.6,en;q=0.4,en-US;q=0.2",
));
$result=curl_exec($ch);//执行一个cURL会话 $code=curl_getinfo($ch,CURLINFO_HTTP_CODE);// 最后一个收到的HTTP代码 if($code!='404' && $result){
return $result; } curl_close($ch);//关闭cURL} /** * 从html内容中筛选链接 * @param string $web_content * @return array */function _filterUrl($web_content) { $reg_tag_a = '/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
$result = preg_match_all($reg_tag_a, $web_content, $match_result);
if ($result) {
return $match_result[1]; } } /** * 修正相对路径 * @param string $base_url * @param array $url_list * @return array */function _reviseUrl($base_url, $url_list) { $url_info = parse_url($base_url);//解析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"];
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; } } /** * 爬虫 * @param string $url * @return array */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() { $file_path = "./url-03.txt";
if(file_exists($file_path)){ unlink($file_path); } $current_url = "http://www.baidu.com"; //初始url //记录url列表 ab- 追加打开一个二进制文件,并在文件末尾写数据 $fp_puts = fopen($file_path, "ab"); //保存url列表 r-只读方式打开,将文件指针指向文件头 $fp_gets = fopen($file_path, "r"); do {
$result_url_arr = crawler($current_url);
echo "<p>$current_url</p>";
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();?>
_getUrlContent
函数中加入下面的设置:curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "username:password");
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
我们通过1和2部分得到的结果差异很大,第1部分能得到四千多条url数据,而第2部分却一直是45条数据。3.file_get_contents/stream_get_contents与curl对比
3.1 file_get_contents/stream_get_contents对比
与 [file_get_contents()]一样,但是 stream_get_contents() 是对一个已经打开的资源流进行操作,并将其内容写入一个字符串返回
$handle = fopen($url##, "r");
#<code style="margin:0px;padding:0px;max-width:100%;font-family:Consolas, Inconsolata, Courier, monospace;white-space:pre;"><span style="color:#4f4f4f;margin:0px;padding:0px;max-width:100%;">$content</span> = file_get_contents(<span style="color:#4f4f4f;margin:0px;padding:0px;max-width:100%;">$url</span>, <span style="margin:0px;padding:0px;max-width:100%;">1024</span> * <span style="margin:0px;padding:0px;max-width:100%;">1024</span>);<br/><span style="font-family:'PingFang SC', 'Microsoft YaHei', SimHei, Arial, SimSun;color:#999999;margin:0px;padding:0px;max-width:100%;text-align:justify;background-color:rgb(238,240,244);">【注】 如果要打开有特殊字符的 URL (比如说有空格),就需要使用进行 URL 编码。</span></code>
3.2 file_get_contents/stream_get_contents与curl对比
- fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen /file_get_contents 好很多。
fopen /file_get_contents 在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。
fopen / file_get_contents 函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
curl 可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen / file_get_contents只能使用get方式获取数据
相关推荐:
以上是PHP爬蟲技術知識點總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
