什么是網(wǎng)絡(luò)爬蟲
大數(shù)據(jù)時代,獲得完整全面的數(shù)據(jù)兔跌,是件極其重要卻并不容易的事情。要真正做好大數(shù)據(jù)時代的分析华望,就需要借助爬蟲的力量。
網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)絡(luò)蜘蛛蓬戚,網(wǎng)絡(luò)機器人)子漩,是一種按照一定的規(guī)則石洗,自動地抓取萬維網(wǎng)信息的程序或者腳本。
如果把互聯(lián)網(wǎng)比喻成一個蜘蛛網(wǎng)缕棵,那么 網(wǎng)絡(luò)爬蟲 就是在網(wǎng)上爬來爬去的蜘蛛挥吵。網(wǎng)絡(luò)爬蟲 通過網(wǎng)頁的鏈接地址來尋找網(wǎng)頁花椭,從網(wǎng)站某一個頁面(通常是首頁)開始,讀取網(wǎng)頁的內(nèi)容丹允,找到在網(wǎng)頁中的其它鏈接地址雕蔽,然后通過這些鏈接地址尋找下一個網(wǎng)頁宾娜,一直遍歷下去,直到把整個網(wǎng)站所有的網(wǎng)頁都抓取完為止嚣艇。
網(wǎng)絡(luò)爬蟲的合法性
網(wǎng)絡(luò)爬蟲引發(fā)的問題
- 性能騷擾
- 法律風(fēng)險
- 隱私泄露
網(wǎng)絡(luò)爬蟲的"性能騷擾"
web服務(wù)器默認接受人類訪問食零,受限于編寫水平和目的寂屏,網(wǎng)絡(luò)爬蟲將會為web服務(wù)器帶來巨大的資源的開銷娜搂。
網(wǎng)絡(luò)爬蟲的法律風(fēng)險
服務(wù)器上的數(shù)據(jù)有產(chǎn)權(quán)歸屬百宇,網(wǎng)絡(luò)爬蟲獲取數(shù)據(jù)后牟利將會帶來法律的風(fēng)險携御。
網(wǎng)絡(luò)爬蟲的隱私泄露
網(wǎng)絡(luò)爬蟲可能具備突破簡單訪問的控制能力憋肖,獲取被保護的數(shù)據(jù)岸更,從而泄露個人隱私膊升。
無論如何,當(dāng)你抓取某個網(wǎng)站的數(shù)據(jù)時评肆,請記住自己是該網(wǎng)站的訪客非区,應(yīng)當(dāng)約束自己的抓取行為征绸,否則他們可能會封禁你的IP,甚至采取更進一步的法律行動淆衷。這就要求下載請求的速度要限定在一個合理值之內(nèi)渤弛,并且還需要設(shè)定一個專屬的用戶代理來標識自己她肯。
Robots協(xié)議
Robots協(xié)議(也稱為爬蟲協(xié)議、機器人協(xié)議等)的全稱是“網(wǎng)絡(luò)爬蟲排除標準”(Robots Exclusion Protocol)畜晰,網(wǎng)站通過Robots協(xié)議告訴搜索引擎哪些頁面可以抓取瑞筐,哪些頁面不能抓取。
根據(jù)協(xié)議块蚌,網(wǎng)站管理員可以在網(wǎng)站域名的根目錄下放一個robots.txt 文本文件,里面可以指定不同的網(wǎng)絡(luò)爬蟲能訪問的頁面和禁止訪問的頁面财松,指定的頁面由正則表達式表示纱控。網(wǎng)絡(luò)爬蟲在采集這個網(wǎng)站之前甜害,首先獲取到這個文件,然后解析到其中的規(guī)則眨攘,然后根據(jù)規(guī)則來采集網(wǎng)站的數(shù)據(jù)嚣州。
注意该肴,這個協(xié)議的存在更多的是需要網(wǎng)絡(luò)爬蟲去遵守,而起不到防止爬蟲的功能秦效。
為什么需要Robots協(xié)議
互聯(lián)網(wǎng)上的網(wǎng)頁是通過超級鏈接互相關(guān)聯(lián)起來的拱雏,從而形成了網(wǎng)頁的網(wǎng)狀結(jié)構(gòu)。爬蟲的工作方式就像蜘蛛在網(wǎng)上沿著鏈接爬來爬去贡耽,最基本的流程可以簡化如下:
- 喂給爬蟲一堆url蒲赂,我們稱之為種子(seeds)刁憋;
- 爬蟲抓取seeds,解析html網(wǎng)頁若皱,抽取其中的超級鏈接;
- 爬蟲接著抓取這些新發(fā)現(xiàn)的鏈接指向的網(wǎng)頁晦譬。
步驟2和步驟3循環(huán)往復(fù)互广。
了解了上面的流程就能發(fā)現(xiàn):對爬蟲來說網(wǎng)站非常被動,只有老老實實被抓取的份像樊。
所以生棍,對于網(wǎng)站的管理者來說扫皱,就存在這樣的需求:
某些路徑下是個人隱私或者網(wǎng)站管理使用捷绑,不想被搜索引擎抓取,比如說日本愛情動作片段多;
不喜歡某個搜索引擎进苍,不愿意被他抓取鸭叙,最有名的就是之前淘寶不希望被百度抓取杠人;
小網(wǎng)站使用的是公用的虛擬主機嗡善,流量有限或者需要付費学歧,希望搜索引擎抓的溫柔點;
某些網(wǎng)頁是動態(tài)生成的袁铐,沒有直接的鏈接指向,但是希望內(nèi)容被搜索引擎抓取和索引忌锯。
網(wǎng)站內(nèi)容的所有者是網(wǎng)站管理員领炫,搜索引擎應(yīng)該尊重所有者的意愿,為了滿足以上等等似舵,就需要提供一種網(wǎng)站和爬蟲進行溝通的途徑砚哗,給網(wǎng)站管理員表達自己意愿的機會砰奕。有需求就有供應(yīng),robots協(xié)議就此誕生仅淑。
Robots寫法
最簡單的robots.txt只有兩條規(guī)則:
- User-agent:指定對哪些爬蟲生效
- Disallow:不允許爬取的目錄
另外常見的附加規(guī)則:
- Crawl-delay: 指定爬蟲抓取的間隔時間(秒)涯竟。這種操作可以進行緩解服務(wù)器壓力空厌。
- Sitemap: 網(wǎng)站地圖,格式為XML筐钟。其中列出網(wǎng)站中的網(wǎng)址以及關(guān)于每個網(wǎng)址的其他數(shù)據(jù)(上次更新的時間篓冲、更改的頻率以及相對于網(wǎng)站上其他網(wǎng)址的重要程度等等)北发,利用這些信息搜索引擎可以更加智能地抓取網(wǎng)站內(nèi)容。
- Allow: 允許爬取的目錄瞭恰,一般和Disallow配合使用狱庇。
舉個??
知乎的robots文件: https://www.zhihu.com/robots.txt
User-agent: *
Crawl-delay: 10
Disallow: /login
Disallow: /logout
Disallow: /resetpassword
Disallow: /terms
Disallow: /search
Disallow: /notifications
Disallow: /settings
Disallow: /inbox
Disallow: /admin_inbox
Disallow: /*?guide*
Disallow: /people/*-*-*-*
簡書的robots文件:http://www.reibang.com/robots.txt
# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
#
# To ban all spiders from the entire site uncomment the next two lines:
User-agent: *
Disallow: /search
Disallow: /notes/
Disallow: /admin/
Disallow: /p/0826cf4692f9
Disallow: /p/d8b31d20a867
Disallow: /collections/*/recommended_authors
Disallow: /trial/*
Disallow: /mobile/campaign/fd2017/*
淘寶的robots文件:https://www.taobao.com/robots.txt
User-agent: Baiduspider
Allow: /article
Allow: /oshtml
Allow: /wenzhang
Disallow: /product/
Disallow: /
User-Agent: Googlebot
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /wenzhang
Allow: /oversea
Disallow: /
User-agent: Bingbot
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /wenzhang
Allow: /oversea
Disallow: /
User-Agent: 360Spider
Allow: /article
Allow: /oshtml
Allow: /wenzhang
Disallow: /
User-Agent: Yisouspider
Allow: /article
Allow: /oshtml
Allow: /wenzhang
Disallow: /
User-Agent: Sogouspider
Allow: /article
Allow: /oshtml
Allow: /product
Allow: /wenzhang
Disallow: /
User-Agent: Yahoo! Slurp
Allow: /product
Allow: /spu
Allow: /dianpu
Allow: /wenzhang
Allow: /oversea
Disallow: /
User-Agent: *
Disallow: /
Robots協(xié)議不是什么技術(shù)壁壘颜启,而只是一種互相尊重的協(xié)議。Robots協(xié)議是建議但非約束性涌萤,網(wǎng)絡(luò)爬蟲可以不遵守口猜,但存在法律風(fēng)險。
估算網(wǎng)站大小
目標網(wǎng)站的大小會影響我們?nèi)绾芜M行爬取川抡。如果是只有幾百個URL的網(wǎng)站崖堤,效率并沒有那么重要耐床;但如果是擁有數(shù)百萬個網(wǎng)頁的站點,使用串行下載可能需要持續(xù)數(shù)月才能完成老玛,這時就需要使用分布式下載來解決钧敞。
估算網(wǎng)站大小的一個簡便方法是檢查其他搜索引擎爬蟲的結(jié)果溉苛∨澹可以通過site參數(shù)獲取該信息。如在 Google 中搜索 site:jianshu.com
三個搜索引擎顯示簡書的網(wǎng)頁數(shù)量都在百萬級。
在域名后面添加URL路徑可以對搜索結(jié)果進行過濾梗摇。
識別網(wǎng)站所用技術(shù)
構(gòu)建網(wǎng)站的技術(shù)類型也會對我們?nèi)绾闻廊‘a(chǎn)生影響伶授。網(wǎng)站所用的框架流纹,以及 AngularJS 之類的動態(tài)加載漱凝,ASP.NET 的會話管理和表單提交都會影響我們的爬蟲策略诸迟。
有一個十分有用的工具可以檢查網(wǎng)站構(gòu)建的技術(shù)類型——builtwith 模塊(只支持python2環(huán)境,python3環(huán)境報錯)扣典。
安裝builtwith之前贮尖,需要安裝pip趁怔。
sudo easy_install pip
pip 是一個現(xiàn)代的,通用的 Python 包管理工具关斜。提供了對 Python 包的查找铺浇、下載、安裝丁稀、卸載的功能。
pip之于python相當(dāng)于maven之于Java线衫,CocoaPos之于OC惑折。
pip安裝完成后,安裝builtwith模塊白热。
pip install builtwith
該模塊將 URL 作為參數(shù)粗卜,下載該 URL 并對其進行分析,然后返回該網(wǎng)站使用的技術(shù)乍恐。
舉個??:
識別網(wǎng)站所有者
對于一些網(wǎng)站茵烈,我們可能會關(guān)心其所有者是誰。為了找到網(wǎng)站的所有者加匈,我們可以使用WHOIS協(xié)議查詢域名的注冊者是誰仑荐。Python中有一個對該協(xié)議的封裝庫。我們可以通過pip進行安裝啥寇。
pip install python-whois
舉個??:
編寫第一個python爬蟲
從最簡單的開始洒扎,使用最好用的 requests 做網(wǎng)絡(luò)訪問袍冷,并且使用操作方便的 beautifulsoup 來解析 html。Python 標準庫中自帶了 xml 模塊邓线,但是性能不夠好煌恢,而且缺乏一些人性化的 API,相比之下症虑,第三方庫 lxml 增加了很多實用功能,性能也更高谍憔,可謂爬蟲處理網(wǎng)頁數(shù)據(jù)的一件利器习贫。
pip install requests
pip install bs4
pip install lxml
我們練手的項目就是爬取簡書新上榜推薦文章的數(shù)據(jù)千元。
#coding=utf-8
import requests
import time
from bs4 import BeautifulSoup
base_url = 'http://www.reibang.com'
add_url = '/recommendations/notes'
num = 0
nowtime = time.time()
while(True):
try:
if num > 1000:
break
first_page = requests.request('get', base_url+ add_url).content
soup = BeautifulSoup(first_page, "lxml")
title_list = [i.get_text() for i in soup.select("a.title")]
for i in title_list:
num+=1
print(num, ' ', i)
try:
nowtime = int(nowtime - 1800)
add_url = '/recommendations/notes?category_id=56&max_id=' + str(nowtime)
except:
break
time.sleep(10)
except Exception as e:
print(e)
break
非常簡單的代碼幸海,難點在于分頁奥务。
稍微研究了一下氯葬,打開瀏覽器的開發(fā)者工具,發(fā)現(xiàn)每次點擊更多按鈕帚称,network 發(fā)送的請求都帶了一個 max_id 參數(shù)闯睹。這里 max_id 顯然是一個 timestamp担神,多點擊幾次后發(fā)現(xiàn),這個 timestamp 基本上是以半小時為單位遞減的所刀。于是通過每次改變 max_id 我們實現(xiàn)了爬蟲的自動分頁功能捞挥。
這就是一個最簡單的爬蟲,一般真正的爬蟲還需要涉及數(shù)據(jù)存儲斩披,這個就交給讀者們自己解決吧垦沉。
最后安利個人博客:http://reinhardhuang.com
參考
- 《用 Python 寫網(wǎng)絡(luò)爬蟲》—— Richard Lawson 著,李斌 譯
- 爬蟲的"盜亦有道"-Robots協(xié)議—— 若與
- 新手向爬蟲(一)利用工具輕松爬取簡書并分析 —— treelake