富貴教你用PHP爬取掘金文章

最近忙完了專案比較空就打算深入學習一些關於爬蟲的知識,以前讀書的時候就喜歡用爬蟲去爬一些學習網站(波多野**老師)。寫這篇部落格是想對之前學習的一些爬蟲知識做一個梳理和交流。希望有大佬指出不足,幫我成長。
新手村任務
下面這些是我2018年這半年業餘時間研究的一些小東西,比較適合剛開始接觸爬蟲的人

平時爬東西常用的工具推薦
- Charles (抓包工具)
- Anyproxy 也是一個抓包工具但是可以程式設計比較好玩
- adb 安卓除錯橋 可以用python指令碼控制安卓手機自動執行指令碼
- simulator 網頁抓包必備、還可以寫自動化測試指令碼
迴歸正題爬掘金文章
首先我打算使用最原始的方式去獲取掘金的文章內容。我使用了PHP的curl和phpQuery來做這件事情。我發現文章內容獲取到的是空。而且像圖片這些資源是用 <image>
這樣的標籤包起來的沒有得到正常解析。
很顯然掘金的文章是非同步載入的。而且通過curl去獲取文章會發現文章內容是加密過的。 (我沒有太多時間去研究他的加密規則) 複製程式碼
我的思路很簡單直接抓取渲染過後的資料。一般來講要達到這個效果可以使用 simulator和phantomjs。使用simulator我本地是OK的好想伺服器爆錯了後來就用了phantomjs。
下面講解一下這個專案需要的依賴和注意事項
1、注意事項(選擇國內的源)
composer 方法一: 修改 composer 的全域性配置檔案(推薦方式) 開啟命令列視窗(windows使用者)或控制檯(Linux、Mac 使用者)並執行如下命令:
composer config -g repo.packagist composer https://packagist.phpcomposer.com 複製程式碼
方法二: 修改當前專案的 composer.json 配置檔案: 開啟命令列視窗(windows使用者)或控制檯(Linux、Mac 使用者),進入你的專案的根目錄(也就是 composer.json 檔案所在目錄),執行如下命令:
composer config repo.packagist composer https://packagist.phpcomposer.com 複製程式碼
2、需要安裝的依賴
composer require "jonnyw/php-phantomjs:4.*" 複製程式碼
3、Linux環境的特殊需求(修改依賴檔案)
namespace JonnyW\PhantomJs\DependencyInjection; /** * Load service container. * * @access public * @return void */ public function load($file = null) { $loader = new YamlFileLoader($this, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('config.yml'); $loader->load('services.yml'); $this->setParameter('phantomjs.cache_dir', sys_get_temp_dir()); $this->setParameter('phantomjs.resource_dir', __DIR__.'/../Resources'); } 複製程式碼
修改PHP.ini開啟一些系統函式

上程式碼
$client = Client::getInstance(); $client->getEngine()->setPath(ROOT_PATH . 'public' . DS . 'phantomjs'); //設定phantomjs位置 $client->getEngine()->addOption('--load-images=false'); $client->getEngine()->addOption('--ignore-ssl-errors=true'); $url = 'https://juejin.im/entry/5c01b3016fb9a04a0b21e766'; $request = $client->getMessageFactory()->createRequest($url, 'GET'); $timeout = 10000; //設定超時 $request->setTimeout($timeout); $response = $client->getMessageFactory()->createResponse(); $client->send($request, $response); $str = $response->getContent(); $num1 = strpos($str, '<article'); $num2 = strpos($str, '</article>'); $re_data = substr($str, $num1, $num2 - $num1); $re_data .= '</article>'; $re_data = str_replace("data-src","src",$re_data); //file_put_contents('3.html', $re_data); return $re_data; 複製程式碼