前言
防砸聲明:此文僅僅能保證入門,不保證商業(yè)生產(chǎn)建瘫。
引用錢洋博士課程的部分內(nèi)容(有刪改):
網(wǎng)絡(luò)爬蟲技術(shù)崭捍,有效的獲取網(wǎng)絡(luò)數(shù)據(jù)資源的重要方式。簡(jiǎn)單的理解啰脚,比如您對(duì)百度貼吧的一個(gè)帖子內(nèi)容特別感興趣殷蛇,而帖子的回復(fù)卻有1000多頁,這時(shí)采用逐條復(fù)制的方法便不可行橄浓。而采用網(wǎng)絡(luò)爬蟲便可以很輕松地采集到該帖子下的所有內(nèi)容粒梦。
網(wǎng)絡(luò)爬蟲的作用,我總結(jié)為以下幾點(diǎn):
- 輿情分析:企業(yè)或政府利用爬取的數(shù)據(jù)荸实,采用數(shù)據(jù)挖掘的相關(guān)方法匀们,發(fā)掘用戶討論的內(nèi)容、實(shí)行事件監(jiān)測(cè)准给、輿情引導(dǎo)等泄朴。
- 企業(yè)的用戶分析:企業(yè)利用網(wǎng)絡(luò)爬蟲重抖,采集用戶對(duì)其企業(yè)或商品的看法、觀點(diǎn)以及態(tài)度祖灰,進(jìn)而分析用戶的需求钟沛、自身產(chǎn)品的優(yōu)劣勢(shì)、顧客抱怨等局扶。
- 科研工作者的必備技術(shù):現(xiàn)有很多研究都以網(wǎng)絡(luò)大數(shù)據(jù)為基礎(chǔ)恨统,而采集網(wǎng)絡(luò)大數(shù)據(jù)的必備技術(shù)便是網(wǎng)絡(luò)爬蟲。利用網(wǎng)絡(luò)爬蟲技術(shù)采集的數(shù)據(jù)可用于研究產(chǎn)品個(gè)性化推薦三妈、文本挖掘畜埋、用戶行為模式挖掘等。
按照陳樹義前輩在《聊聊整體性學(xué)習(xí)方法》一文中提到的思想畴蒲,本文思路如下:
獲扔瓢啊:目前都有哪些爬蟲技術(shù)?
理解:這些爬蟲技術(shù)的特色是什么饿凛?
擴(kuò)展:快速上手一下cdp4j爬蟲技術(shù)狞玛。
糾錯(cuò):解析網(wǎng)頁過程中踩過的坑與填坑之路。
應(yīng)用:實(shí)戰(zhàn)爬取網(wǎng)易新聞評(píng)論內(nèi)容涧窒。
正文
一心肪、目前都有哪些爬蟲技術(shù),及其特色都是什么纠吴?
? 先說一句我不是專業(yè)搞爬蟲的硬鞍,從2019-07-06到2019-07-11累計(jì)學(xué)習(xí)5天。這篇文章是對(duì)我這5天學(xué)習(xí)的總結(jié)戴已。以我淺顯的了解固该,在此我列出我曾經(jīng)嘗試過后來又放棄了的框架,最后壓軸(zhoù)再寫我正在使用的框架糖儡。目前有以下流行的爬蟲框架技術(shù):
- Apache Nutch(高大上)
Nutch這個(gè)框架運(yùn)行需要Hadoop伐坏,Hadoop需要開集群,對(duì)于想要快速入門爬蟲的我是望而卻步了......
一些資源地址列在這里握联,說不定以后會(huì)學(xué)習(xí)呢桦沉。
- Crawler4j(感覺很強(qiáng))
從它的包名上可以看出這個(gè)框架來自加州大學(xué)歐文分校。我下載下來Demo運(yùn)行了一下金闽,感覺很強(qiáng)纯露!但他的官方文檔介紹很簡(jiǎn)潔,Demo只是運(yùn)行了一下沒看懂怎么用代芜。之所以感覺很強(qiáng)埠褪,是看見了好的厲害的API,當(dāng)然也有一些加州大學(xué)的名氣影響。
- WebMagic(國產(chǎn))
根據(jù)網(wǎng)上介紹钞速,這個(gè)框架產(chǎn)自曾就職于大眾點(diǎn)評(píng)的黃億華大佬贷掖,但是,無論GitHub還是碼云上這個(gè)倉庫已經(jīng)兩年沒有更新了玉工,其中有一個(gè)致命的“Bug”羽资,不能爬https的鏈接。作者在GitHub的issue中明確說明會(huì)在下一個(gè)版本(0.7.4)中修復(fù)此“Bug”遵班,但是,兩年過去了潮改,依然沒有發(fā)布下一個(gè)版本狭郑,截止2019年7月11號(hào),GitHub上依然是0.7.3版本汇在,可能作者遇到了某種不可抗拒力量翰萨,導(dǎo)致無法維護(hù)下去。下圖來自GitHub issues
- Spiderman2(國產(chǎn))
這個(gè)聽名字就挺霸氣的糕殉,和蜘蛛俠電影齊名亩鬼。我也是下載下來Demo運(yùn)行了一下,但是運(yùn)行啥啥報(bào)錯(cuò)......
而且官方庫也沒有提供文檔阿蝶。
但是雳锋,之所以列出來這個(gè)庫,是因?yàn)樽髡咴诖a云的issue中現(xiàn)場(chǎng)教學(xué)感動(dòng)了我羡洁。
- WebController(國產(chǎn)·合肥工業(yè)大學(xué))
當(dāng)我根據(jù)這個(gè)庫的包名搜索出合肥工業(yè)大學(xué)時(shí)玷过,心中只有兩個(gè)字:牛X!
維護(hù)這個(gè)庫的兄弟還煞費(fèi)苦心的把README.md全英文書寫筑煮。不過同樣是因?yàn)槲臋n過于簡(jiǎn)陋辛蚊。Demo運(yùn)行了幾個(gè),不知道運(yùn)行出來個(gè)啥真仲。
之所以貼出來這個(gè)袋马,確實(shí)是因?yàn)樗贕itHub上2000+star震驚到我了,同樣身為大學(xué)生的我秸应,求學(xué)三年虑凛,毫無產(chǎn)出,甚是慚愧灸眼。定當(dāng)以前輩勵(lì)志卧檐,再加努力。
- HtmlUnit(經(jīng)典·適合靜態(tài)網(wǎng)頁)
這個(gè)框架堪稱經(jīng)典焰宣,也是我們暑期實(shí)訓(xùn)老師講解的框架霉囚。有近乎完整的文檔介紹。
但是匕积,HtmlUnit中webClient.getPage("url")只能get到靜態(tài)網(wǎng)頁內(nèi)容盈罐。但是榜跌,當(dāng)今世界,靜態(tài)網(wǎng)頁已經(jīng)寥寥可數(shù)了盅粪,大都是與后臺(tái)交互的動(dòng)態(tài)網(wǎng)頁钓葫,很多數(shù)據(jù)都是經(jīng)過后臺(tái)獲取,渲染之后才能呈現(xiàn)在網(wǎng)頁上票顾。據(jù)我5天淺顯的學(xué)習(xí)础浮,發(fā)現(xiàn)單純的HtmlUnit無法爬取動(dòng)態(tài)網(wǎng)頁內(nèi)容。
大家可以試一下奠骄,打開一篇網(wǎng)易新聞豆同,然后右鍵查看源代碼,你會(huì)發(fā)現(xiàn)含鳞,你所看到的頁面和源代碼內(nèi)容并不是一一對(duì)應(yīng)的影锈。
- Jsoup(經(jīng)典·適合靜態(tài)網(wǎng)友)
這個(gè)框架堪稱經(jīng)典,也是我們暑期實(shí)訓(xùn)老師講解的框架蝉绷。有近乎完整的文檔介紹鸭廷。
和HtmlUnit同樣,只能get到靜態(tài)內(nèi)容熔吗。
不過辆床,這個(gè)框架有個(gè)有個(gè)優(yōu)點(diǎn),具有很強(qiáng)大的解析網(wǎng)頁的功能磁滚。
- selenium(Google多名大佬參與開發(fā))
感覺很厲害佛吓,實(shí)際真的很厲害,看官網(wǎng)以及其他人的介紹垂攘,說是真正模擬瀏覽器维雇。GitHub1.4w+star,你沒看錯(cuò)晒他,上萬了吱型。但是我硬是沒配好環(huán)境。入門Demo就是沒法運(yùn)行成功陨仅,所以就放棄了津滞。
- cdp4j(今天的主角)
使用前提:
安裝Chrome瀏覽器,即可灼伤。
簡(jiǎn)單介紹:
HtmlUnit的優(yōu)點(diǎn)在于触徐,可以方便的爬取靜態(tài)網(wǎng)友;缺點(diǎn)在于狐赡,只能爬取靜態(tài)網(wǎng)頁撞鹉。
selenium的優(yōu)點(diǎn)在于,可以爬取渲染后的網(wǎng)頁;缺點(diǎn)在于鸟雏,需要配環(huán)境變量等等享郊。
將二者整合,取長(zhǎng)補(bǔ)短孝鹊,就有了cdp4j炊琉。
之所以選用它,是因?yàn)檎娴姆奖愫糜糜只睿夜俜轿臋n詳細(xì)苔咪,Demo程序基本都能跑起來,類名起的見名知意皇钞。想當(dāng)年學(xué)軟件工程的時(shí)候悼泌,一直在納悶,為什么要寫文檔啊夹界,我程序能實(shí)現(xiàn)功能不就得了?現(xiàn)如今隘世,看著如此詳實(shí)的文檔可柿,留下了激動(dòng)而又悔恨的淚水......
cdp4j有很多功能:
a. 獲得渲染后的網(wǎng)頁源碼
b. 模擬瀏覽器點(diǎn)擊事件
c. 下載網(wǎng)頁上可以下載的文件
d. 對(duì)網(wǎng)頁進(jìn)行截屏或轉(zhuǎn)PDF打印
e. 等等
更多詳細(xì)信息可以自行去如下三個(gè)地址中探索發(fā)現(xiàn):
小結(jié)
我在正文列出了9個(gè)爬蟲框架。有強(qiáng)如Apache丙者、Google大佬開發(fā)維護(hù)复斥,也有諸如我國合肥工業(yè)大學(xué)學(xué)生的作品。其實(shí)各有各自的特色械媒,弱水三千目锭,我想全喝,但沒有那個(gè)能力纷捞。所以目前只飲一瓢痢虹,就是cdp4j了。
二主儡、快速上手一下cdp4j爬蟲技術(shù)
首先奖唯,再強(qiáng)調(diào)一點(diǎn):使用前提是安裝了Chrome瀏覽器
當(dāng)然,不能憑空使用糜值,還需要Maven依賴
<dependency>
<groupId>io.webfolder</groupId>
<artifactId>cdp4j</artifactId>
<version>3.0.12</version>
</dependency>
<!-- 2.2.1 版本的cdp4j不用導(dǎo)入winp丰捷;3.0+ 版本的cdp4j需要導(dǎo)入此包 -->
<!-- https://mvnrepository.com/artifact/org.jvnet.winp/winp -->
<dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
<version>1.28</version>
</dependency>
先看一下官網(wǎng)給出的HelloWorld
看出來我貼的是一張圖片了嗎?所以先別著急敲寂汇,因?yàn)檫@個(gè)程序還需要稍作修改病往,如下:
import io.webfolder.cdp.Launcher;
import io.webfolder.cdp.session.Session;
import io.webfolder.cdp.session.SessionFactory;
import static java.util.Arrays.asList;
public class HelloWorld {
public static void main(String[] args) {
Launcher launcher = new Launcher();
try (SessionFactory factory = launcher.launch(asList("--disable-gpu",
"--headless"))) {
String context = factory.createBrowserContext();
try (Session session = factory.create(context)) {
// 設(shè)置要爬的網(wǎng)站鏈接,必須要有http://或https://
session.navigate("https://www.baidu.com");
// 默認(rèn)timeout是10*1000 ms骄瓣,也可以像下面這樣手動(dòng)設(shè)置
session.waitDocumentReady(15 * 1000);
// 通過session得到渲染后的html內(nèi)容
String html = session.getContent();
System.out.println(html);
}// session創(chuàng)建結(jié)束
// 處理瀏覽器上下文停巷,源碼:contexts.remove(browserContextId)
// 意思應(yīng)該是將后臺(tái)瀏覽器進(jìn)程關(guān)閉
// 我曾經(jīng)嘗試將此舉注釋,只保留下面的launcher.getProcessManager().kill();
// 依然可以關(guān)閉后臺(tái)進(jìn)程,但是官方給的代碼有這句叠穆,那就帶著吧少漆,或許有其他作用。
factory.disposeBrowserContext(context);
}// factory創(chuàng)建結(jié)束
// 真正的關(guān)閉后臺(tái)進(jìn)程
launcher.getProcessManager().kill();
}// main方法結(jié)束
}
上面的代碼你可以手動(dòng)敲一遍硼被,當(dāng)然一般都是復(fù)制粘貼的示损。
與截圖不同的是:
這里的factory和session是在兩個(gè)不同的try-with-resource語句中創(chuàng)建的,
創(chuàng)建factory時(shí)多了一句 asList("--disable-gpu","--headless") 這個(gè)作用就是不啟用GPU加速嚷硫,不彈出瀏覽器
在最后對(duì)BrowserContex以及l(fā)auncher進(jìn)行了關(guān)閉操作以達(dá)到回收內(nèi)存的目的检访。
大家如果不理解這段代碼的作用,可以自行運(yùn)行一下兩種代碼仔掸,然后打開任務(wù)管理器脆贵,查看IDEA進(jìn)行下的子進(jìn)程。
運(yùn)行結(jié)束后再看一下任務(wù)管理器起暮,如果執(zhí)行了關(guān)閉操作卖氨,那么IDEA下的子進(jìn)程會(huì)被關(guān)閉,否則负懦,有兩種情況:
創(chuàng)建factory時(shí)候识补,沒有加上 asList("--disable-gpu","--headless") 這樣會(huì)彈出一個(gè)Chrome瀏覽器乓诽,需要手動(dòng)進(jìn)行關(guān)閉
創(chuàng)建factory時(shí)候杀饵,加上了 asList("--disable-gpu","--headless") 這樣IDEA進(jìn)程的子進(jìn)程脉漏,也就是上圖的Google Chrome會(huì)駐留在后臺(tái),占據(jù)內(nèi)存資源颗品。
小結(jié)
? 說白了肯尺,cdp4j就是一個(gè)模擬瀏覽器,區(qū)別于HtmlUnit躯枢,這里是真的用到了瀏覽器则吟,如果代碼寫的不對(duì),還會(huì)彈出瀏覽器闺金,嚇你一跳 : )
? 目前只是簡(jiǎn)簡(jiǎn)單單的獲取到了渲染后的html逾滥,真正的爬蟲可不僅僅就這。
三败匹、解析網(wǎng)頁過程中踩過的坑與填坑之路
- 啥是xPath寨昙?
詳細(xì)介紹可以參考W3cSchool XPath 簡(jiǎn)介 或者 Runoob XPath 簡(jiǎn)介
我在這里簡(jiǎn)單總結(jié)一下:xPath是用來遍歷DOM樹的。
你要是敢問我啥是DOM樹掀亩,我可就舉起來拖鞋抽你了 : ) 哈哈舔哪,開玩笑,同樣也是看一下W3CSchool HTML DOM 簡(jiǎn)介 或者 Runoob HTML DOM 簡(jiǎn)介
- 如何快速獲取一個(gè)節(jié)點(diǎn)的xPath槽棍?
我們暑期實(shí)訓(xùn)老師是按下F12捉蚤,然后找到對(duì)應(yīng)節(jié)點(diǎn)抬驴,再從上到下一個(gè)一個(gè)的數(shù)出來的xPath。
第一次見這樣操作的時(shí)候缆巧,由于新鮮感過于強(qiáng)烈布持,所以也就沒有感到有多麻煩。不過陕悬,數(shù)的次數(shù)多了题暖,總覺得這樣不行。應(yīng)該有更快更好的方法獲取xPath捉超。
還記得SpiderMan2嗎胧卤?自風(fēng)老師在碼云的issue里面親身教學(xué):Chrome獲取XPath的方法
整了半天,原來人家Chrome瀏覽器早就替我們實(shí)現(xiàn)好了拼岳,就知道我們要用到xPath干壞事枝誊。
- xPath具體怎么用?
自風(fēng)老師教的copy xPath直接用的話惜纸,只能是一個(gè)節(jié)點(diǎn)叶撒。
實(shí)際上,有時(shí)候我們需要一次性拿到很多節(jié)點(diǎn)耐版,比如說xPath路徑都是div/p,這時(shí)候我們可以寫成“//div/p”痊乾,又有時(shí)候,我們需要拿到指定class的div下的p椭更,那么語法就是“//div[@class='classname']/p”
更詳細(xì)的用法可以參考 Runoob XPath 語法
- 怎樣快速解析一個(gè)html,拿到想要的內(nèi)容蛾魄?
雖說cdp4j自帶xPath解析功能虑瀑,但要說解析html,還要屬Jsoup最專業(yè):Jsoup中文教程
Jsoup支持xPath和CSS選擇器滴须,學(xué)前端的同學(xué)看到CSS選擇器應(yīng)該會(huì)很激動(dòng)吧舌狗,我頭一次看到內(nèi)心是:竟然還有這種操作!
小結(jié)
? xPath扔水、Jsoup這些新名詞痛侍,很多人(比如我)大學(xué)上了3年,還是頭一次聽說魔市,所以需要一些時(shí)間去接近主届,熟悉最終才能掌握。
四待德、實(shí)戰(zhàn)爬取網(wǎng)易新聞評(píng)論內(nèi)容
先發(fā)一下君丁,詳情待更......
【項(xiàng)目源碼】 進(jìn)去找 News163CommentCrawlerDemo 或者 News163CommentCrawlerDemo.zip
注意:Maven需要指定Java1.8 否則try-with-resource中不能使用外部數(shù)據(jù)。