摘要:最近看了很多關(guān)于爬蟲入門的文章,發(fā)現(xiàn)其中大部分都是以知乎為爬取對象,所以這次我也以知乎為目標(biāo)來進(jìn)行爬取的演示,用到的爬蟲框架為編寫的。項(xiàng)目地址這次寫的內(nèi)容為爬取知乎的用戶,下面就是詳細(xì)說一下寫爬蟲的過程了。
最近看了很多關(guān)于爬蟲入門的文章,發(fā)現(xiàn)其中大部分都是以知乎為爬取對象,所以這次我也以知乎為目標(biāo)來進(jìn)行爬取的演示,用到的爬蟲框架為 PHP 編寫的 Beanbun。
項(xiàng)目地址:https://github.com/kiddyuchina/Beanbun
這次寫的內(nèi)容為爬取知乎的用戶,下面就是詳細(xì)說一下寫爬蟲的過程了。
爬取知乎用戶的思路比較簡單,就是從某個(gè)用戶開始,先抓取這個(gè)用戶關(guān)注的人和關(guān)注他的人,抓取到這些人后,再抓取他們的相關(guān)的用戶。
現(xiàn)在知乎是可以使用游客身份進(jìn)行瀏覽的,也省去了注冊和登錄這一部分。先隨便找個(gè)大V吧,因?yàn)樗麄兊年P(guān)注者比較多,我選擇的是大名鼎鼎的張公子,張公子的關(guān)注者有13萬,就是說只爬取他的關(guān)注者,我們都能有13萬的用戶數(shù)據(jù)~
在用戶頁面中打開chrome瀏覽器的開發(fā)者選項(xiàng),點(diǎn)擊關(guān)注者后就可以看到請求地址和數(shù)據(jù)。
就以這個(gè)作為入口開始爬取了~
此處跳過框架的安裝和隊(duì)列的開啟,直接上爬蟲的代碼:
(如果需要跳過的部分,可以看一下文檔)
name = "zhihu_user"; $beanbun->count = 5; $beanbun->interval = 4; $beanbun->seed = "https://www.zhihu.com/api/v4/members/zhang-jia-wei/followers?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=0&limit=20"; $beanbun->logFile = __DIR__ . "/zhihu_user_access.log";
上面是對爬蟲的配置,開啟5個(gè)進(jìn)程同時(shí)爬取,設(shè)置爬取間隔為4秒。在爬去前,我們還要設(shè)置一下請求的headers,好讓網(wǎng)站認(rèn)為是人類再瀏覽他- -。headers的內(nèi)容從開發(fā)者選項(xiàng)中一股腦粘貼進(jìn)來。
$beanbun->beforeDownloadPage = function ($beanbun) { // 在爬取前設(shè)置請求的 headers $beanbun->options["headers"] = [ "Host" => "www.zhihu.com", "Connection" => "keep-alive", "Cache-Control" => "max-age=0", "Upgrade-Insecure-Requests" => "1", "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36", "Accept" => "application/json, text/plain, */*", "Accept-Encoding" => "gzip, deflate, sdch, br", "authorization" => "oauth c3cef7c66a1843f8b3a9e6a1e3160e20", ]; };
而在請求到數(shù)據(jù)后,我還需要把他們存到數(shù)據(jù)庫中,因?yàn)橹饕茄菔荆灾槐4嬗脩舻膇d,name,follower,following這四個(gè)數(shù)據(jù)。
// 數(shù)據(jù)庫配置 Db::$config["zhihu"] = [ "server" => "127.0.0.1", "port" => "3306", "username" => "xxxx", "password" => "xxxx", "database_name" => "zhihu", "charset" => "utf8", ]; $beanbun->afterDownloadPage = function ($beanbun) { // 獲取的數(shù)據(jù)為 json,先解析 $data = json_decode($beanbun->page, true); // 如果沒有數(shù)據(jù)或報(bào)錯(cuò),那可能是被屏蔽了。就把地址才重新加回隊(duì)列 if (isset($data["error"]) || !isset($data["data"])) { $beanbun->queue()->add($beanbun->url); $beanbun->error(); } // 如果本次爬取的不是最后一頁,就把下一頁加入隊(duì)列 if ($data["paging"]["is_end"] == false) { $beanbun->queue()->add($data["paging"]["next"]); } $insert = []; $date = date("Y-m-d H:i:s"); foreach ($data["data"] as $user) { // 如果關(guān)注者或者關(guān)注的人小于5個(gè),就不保存了 if ($user["follower_count"] < 5 || $user["following_count"] < 5) { continue ; } $insert[] = [ "id" => $user["id"], "name" => $user["name"], "follower" => $user["follower_count"], "following" => $user["following_count"], "created_at" => $date, ]; // 把用戶的關(guān)注者和關(guān)注的人列表加入隊(duì)列 $beanbun->queue()->add("https://www.zhihu.com/api/v4/members/" . $user["url_token"] . "/followers?include=data%5B*%5D.following_count%2Cfollower_count&limit=20&offset=0"); $beanbun->queue()->add("https://www.zhihu.com/api/v4/members/" . $user["url_token"] . "/followees?include=data%5B*%5D.following_count%2Cfollower_count&limit=20&offset=0"); } } if (count($insert)) { Db::instance("zhihu")->insert("zhihu_user", $insert); } // 把剛剛爬取的地址標(biāo)記為已經(jīng)爬取 $beanbun->queue()->queued($beanbun->queue); }; // 不需要框架來發(fā)現(xiàn)新的網(wǎng)址, $beanbun->discoverUrl = function () {}; $beanbun->start();
接下來在命令行運(yùn)行爬蟲
$ php zhihu_user.php start
再去看一眼數(shù)據(jù)庫,源源不斷的用戶數(shù)據(jù)保存進(jìn)來了~
在一切順利的情況下,我又稍微作了一下死,把爬取的間隔減到了2秒,于是在10幾分鐘之后,我被知乎封掉了....
這種情況比較常見的解決方式就是使用代理,下面就在原有爬蟲基礎(chǔ)上,增加一個(gè)簡單的可定時(shí)更新的代理池。
先停止爬蟲
$ php zhihu_user.php stop
網(wǎng)上有很多免費(fèi)代理的網(wǎng)站,我隨便選了一個(gè)提供免費(fèi)代理的網(wǎng)站,爬取到代理的數(shù)據(jù)后,先請求一下163,如果成功的話就加入代理池。
function getProxies($beanbun) { $client = new GuzzleHttpClient(); $beanbun->proxies = []; $pattern = "/(.+) (d+) (.+)(HTTP|HTTPS) get("http://www.mimiip.com/gngao/$i"); $html = str_replace([" ", " ", " "], "", $res->getBody()); preg_match_all($pattern, $html, $match); foreach ($match[1] as $k => $v) { $proxy = strtolower($match[4][$k]) . "://{$v}:{$match[2][$k]}"; echo "get proxy $proxy "; try { $res = $client->get("http://mail.163.com", [ "proxy" => $proxy, "timeout" => 6 ]); echo "success. "; } catch (Exception $e) { echo "error. "; } } } } if ($argv[1] == "start") { getProxies($beanbun); } $beanbun->startWorker = function($beanbun) { // 每隔半小時(shí),更新一下代理池 Beanbun::timer(1800, "getProxies", $beanbun); };再在之前的 beforeDownloadPage 中加入
if (isset($beanbun->proxies) && count($beanbun->proxies)) { $beanbun->options["proxy"] = $beanbun->proxies[array_rand($beanbun->proxies)]; }再次啟動(dòng)爬蟲,爬蟲還會(huì)接著之前的隊(duì)列繼續(xù)爬取。
$ php zhihu_user.php start再看看數(shù)據(jù)庫,使用代理可能會(huì)比之前慢一些,不過數(shù)據(jù)又繼續(xù)增加了。
最終的代碼可以在 Github 上查看https://github.com/kiddyuchin...
例子中的代理池還是比較簡陋的,只是用來說明框架的靈活,而爬取到數(shù)據(jù)在這里就不做圖表進(jìn)行分析了,希望大家關(guān)注的也是寫爬蟲的過程。
最后如果你對這篇文章感興趣,希望能到 Github 上給個(gè) star 啦,謝謝~https://github.com/kiddyuchin...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22915.html
相關(guān)文章
php爬蟲:知乎用戶數(shù)據(jù)爬取和分析
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。本程序抓取的是知乎對外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
php爬蟲:知乎用戶數(shù)據(jù)爬取和分析
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。本程序抓取的是知乎對外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
php爬蟲:知乎用戶數(shù)據(jù)爬取和分析
摘要:背景說明小拽利用的寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎用戶的基本信息同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。本程序抓取的是知乎對外提供用戶訪問的個(gè)人信息頁面抓取過程需要攜帶用戶才能獲取頁面。 背景說明:小拽利用php的curl寫的爬蟲,實(shí)驗(yàn)性的爬取了知乎5w用戶的基本信息;同時(shí),針對爬取的數(shù)據(jù),進(jìn)行了簡單的分析呈現(xiàn)。demo 地址 php的spider代碼和用戶dashboard的展現(xiàn)代碼...
發(fā)表評論
0條評論
tomato
男|高級講師
TA的文章
閱讀更多
Tor Browser 11.0 發(fā)布
閱讀 1710·2021-11-12 10:36
知識圖譜是什么?一文了解其技術(shù)與應(yīng)用場景案例
閱讀 1628·2021-11-12 10:36
關(guān)于SSL證書10大統(tǒng)計(jì)數(shù)據(jù)
閱讀 3452·2021-11-02 14:46
sass介紹及使用
閱讀 3822·2019-08-30 15:56
CSDN 文章自動(dòng)顯示全文
閱讀 3575·2019-08-30 15:55
30分鐘完成JavaScript中的記憶游戲
閱讀 1469·2019-08-30 15:44
另一種方式實(shí)現(xiàn)事務(wù)碼SE16里的結(jié)果集修改
閱讀 1056·2019-08-30 14:00
web前端性能優(yōu)化
閱讀 2744·2019-08-29 18:41
閱讀需要支付1元查看