一、網絡爬蟲
定義:一個程序腳本,可以自動地抓取互聯網上信息的腳本。
(一)爬蟲可以解決的問題
- 解決冷啓動問題
- 搜索引擎的根基,做搜索引擎少不了爬蟲
- 建立知識圖譜,幫助建立機器學習知識圖譜
- 可以製作各種商品的比價軟件、趨勢分析
(二)爬蟲工程師的進階之路
初級爬蟲工程師
- web 前端的知識: HTML、CSS、JavaSc1ipt、 DOM、 DHTML 、Ajax、jQuery、json 等
- 正則表達式, 能提取正常一般網頁中想要的信息,比如某些特殊的文字, 鏈接信息, 知道什麼是懶惰, 什麼是貪婪型的正則
- 會使用 XPath 等獲取一些DOM 結構中的節點信息
- 知道什麼是深度優先, 廣度優先的抓取算法, 及實踐中的使用規則
- 能分析簡單網站的結構, 會使用urllib或requests 庫進行簡單的數據抓取
中級爬蟲工程師
- 瞭解什麼事HASH,會簡單地使用MD5,SHA1等算法對數據進行HASH一遍存儲
- 熟悉HTTP,HTTPS協議的基礎知識,瞭解GET,POST方法,瞭解HTTP頭中的信息,包括返回狀態碼,編碼,user-agent,cookie,session等
- 能設置user-agent進行數據爬取,設置代理等
- 知道什麼事Request,什麼事response,會使用Fiddler等工具抓取及分析簡單地網絡數據包;對於動態爬蟲,要學會分析ajax請求,模擬製造post數據包請求,抓取客戶端session等信息,對於一些簡單的網站,能夠通過模擬數據包進行自動登錄。
- 對於一些難搞定的網站學會使用phantomjs+selenium抓取一些動態網頁信息
- 併發下載,通過並行下載加速數據爬取;多線程的使用。
高級爬蟲工程師
- 能夠使用Tesseract,百度AI,HOG+SVM,CNN等庫進行驗證碼識別。
- 能使用數據挖掘技術,分類算法等避免死鏈。
- 會使用常用的數據庫進行數據存儲,查詢。比如mongoDB,redis;學習如何通過緩存避免重複下載的問題。
- 能夠使用機器學習的技術動態調整爬蟲的爬取策略,從而避免被禁IP封禁等。
- 能使用一些開源框架scrapy,scrapy-redis等分佈式爬蟲,能部署掌控分佈式爬蟲進行大規模數據爬取。
二、搜索引擎
(一)搜索引擎的主要組成
通用爬蟲:就是將互聯網上的頁面整體的爬取下來之後,保存到本地
通用爬蟲想要爬取頁面,需要頁面的url,但是搜索引擎是可以搜索所有網頁的。那麼通用爬蟲url就要涉及到所有網頁。這個“所有”是如何做到的?
- 新網站向搜索引擎主動提交地址
- 在其他網頁上設置新網站鏈接
- 搜索引擎的DNS解析服務商(比如DNSPod等)合作,新網站域名將被快速抓取
(二)搜索引擎的工作流程
第一步:抓取網頁
通過將待爬取的url加入到通用爬蟲的url隊列中,進行頁面內容的爬取。
第二步:數據存儲
將爬取下來的網頁保存到本地,這個過程中會有一定的去重操作。如果某個網頁的內容大部分重複,搜索引擎可能不會保存。
第三步:預處理
- 提取文字
- 中文分詞
- 消除噪音(比如版權聲明文字、導航條、廣告等…)
- 索引處理
第四步:提供檢索服務,網站排名
(三)搜索引擎的侷限性
- 搜索引擎只能爬取原網頁,但是頁面90%的內容都是無用的
- 搜索引擎不能滿足不同行業,不同領域,不同背景的特定需求
- 通用搜索引擎只能爬取文字信息,對於視頻,文件,音頻等其他信息無法爬取
- 只能基於關鍵字查詢,無法基於語義查詢
三、聚焦爬蟲
聚焦爬蟲在實施網頁抓取是會對內容進行處理篩選,儘量保證只抓取與需求相關的網頁信息。
四、爬蟲準備工作
(一)robots協議
定義:網絡爬蟲排除標準
作用:告訴搜索引擎哪些可以爬取,哪些不可以爬取
(二)sitemap–網站地圖
就是一個網站地圖,可以指導我們查看哪些網頁下有哪些內容
https://help.bj.cn/
(三)估算網頁的大小
在百度中輸入:site:目標網站的地址
(四)識別網站使用了何種技術
爲了更好的瞭解網站,抓取該網站的信息,我們可以先了解一下該網站大致所使用的的技術架構。
(五)尋找網站的所有者
有時候,我們需要知道網站的所有者是誰,這裏在技術上有個簡單地方法可以參考:
安裝python-whois:pip install python-whois
import whois
whois.whois(‘http://www.sina.com.cn’)
五、http和https
(一)什麼是http協議
http:超文本傳輸協議
它是一個規範,約束髮布和接收html頁面的規範。
https (Hypertext Transfer Protocol over Secure Socket Layer)
簡單講是http的安全版,在http下加入SSL層
(二)默認端口號
http協議的端口號:80
https協議的端口號:443
(三)http請求的特點
-
是一個應用層協議
-
無連接
每次請求都是獨立的
http1.1增加了一個Connection:keep-alive,這個頭表示,客戶端和服務器的鏈接是一個長連接。
-
無狀態
無狀態表示客戶端每次請求都不能記錄請求狀態。也就是兩條請求之間無法進行通信。
cookie和session可以幫助記錄狀態。
(四)url–統一資源定位符
爲什麼可以通過url來定義互聯網上的任意資源?
基本格式
scheme://host[:port#]/path/…/[?query-string][#anchor]
- scheme:協議(例如:hhttp,https,ftp)
- host:服務器的IP地址或者域名,可以定位電腦
- port:端口號,用來從互聯網上進入電腦
- path:資源路徑,爲了在電腦中找到對應的資源
- query-string:參數,發送給http服務器的數據
- anchor:錨(跳轉到網頁的指定錨點位置)
有三種特殊符號
- ?:問號後面就是請求參數
- &:請求參數用&連接
- #:表示錨點,在請求這個url時,頁面會跳入錨點的指定位置
解析url
在python中,有一個模塊可以幫助我們解析url
from urllib import parse
url = 'http://localhost.com:8080/index.htm?username="zhangsan"&password="123"'
print(parse.urlparse(url))
結果:
ParseResult(
scheme='http',
netloc='localhost.com:8080',
path='/index.htm',
params='',
query='',
fragment='')
(五)http工作過程
-
地址解析,將url解析出對應的內容
-
封裝http請求數據包
-
封裝成TCP包,建立TCP連接
TCP的三次握手
- 第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確定
- 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態
- 第三次握手:客戶端收到服務器的SYN+ACK包,想服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態
完成三次握手,客戶端與服務器開始傳送數據
-
客戶端發送請求
-
服務器發送響應
-
服務器關閉TCP連接
(六)當我們在瀏覽器輸入一個url時,爲什麼可以加載出一個頁面?
在抓包的過程中,請求了一個url,會出現很多的資源請求
- 當我們在瀏覽器中輸入一個url,客戶端會發送這個url對應的一個請求到指定服務器獲取內容
- 服務器接收到這個請求,解析出對應的內容,之後將內容封裝到響應裏面發送給客戶端,比如index.html
- 當客戶端拿到這個html頁面,會查看這個頁面中是否有css、js、image等url,如果有,再分別進行請求,獲取到這些資源
- 客戶端會通過html的語法,將獲取到的所有內容完美的顯示出來
(七)客戶端請求
1.請求的組成
請求行、請求頭、空行、請求數據四個部分組成
2.請求方法get/post
get請求
從服務器上獲取資源,通過請求參數來告訴服務器獲取什麼資源。請求參數是在url裏面的?後,使用&拼接,數據不安全,傳輸參數的大小受限。
post請求
向服務器傳遞數據,數據是封裝在請求中的實體,可以傳遞更多內容,也更安全。
區別
- get是從服務器獲取數據,post是向服務器傳遞數據
- get不安全,因爲參數拼接在url後面。post比較安全,因爲參數是放在實體裏面
- get傳參大小受限,post不受限
3.重要的請求頭
User-Agent(瀏覽器名稱):客戶端請求標識
Accept(傳輸文件類型):允許傳入的文件類型
Referer(頁面跳轉處):表明產生請求的網頁來自於哪個url,用戶是從該
Referer頁面訪問到當前請求的頁面
Cookie:在做登錄的時候需要封裝這個頭
Content-Type(post數據類型):POST請求裏用來表示的內容類型
例:Content-Type: text/html;charset=utf-8
發送post請求時,需要特別注意headers的一些屬性
Content-Length: 144: 是指發送的表單數據長度爲144,也就是字符個數是144個
X-Requested-With: XMLhttpRequest :表示Ajax異步請求
(八)服務響應
1.響應的組成
狀態行,響應頭,空行,響應正文
2.重要響應頭
Content-Type:text/html;charset=UTF-8:告訴客戶端,資源文件的類型,還有字符編碼
3.狀態碼
100~199:表示服務器成功接收部分請求,要求客戶端繼續提交其餘請求才能完成整個處理過程。
200~299:表示服務器成功接收請求並已完成整個處理過程。常用200(OK 請求成功)。
300~399:爲完成請求,客戶需進一步細化請求。例如:請求的資源已經移動一個新地址、常用302(所請求的頁面已經臨時轉移至新的url)、307和304(使用緩存資源)。
400~499:客戶端的請求有錯誤,常用404(服務器無法找到被請求的頁面)、403(服 務器拒絕訪問,權限不夠—DDos)。
500~599:服務器端出現錯誤,常用500(請求未完成。服務器遇到不可預知的情況)。
(九)Cookie和Session
服務器和客戶端的交互僅限於請求/響應過程,結束之後便斷開,在下一次請求時,服
務器會認爲新的客戶端。
爲了維護他們之間的連接,讓服務器知道這是前一個用戶發送的請求,必須在一個地方
保存客戶端的信息。
Cookie:通過在 客戶端 記錄的信息確定用戶的身份。
Session:通過在 服務器端 記錄的信息確定用戶的身份。
六、hash算法
(一)給一個字符串進行加密
import hashlib
def get_hex(value):
#1.c創建一個加密對象
md5_ = hashlib.md5()
#2.將需要加密的內容update到md5對象中
#將字符串轉化成bytes類型兩種方法:
#str.encode('utf-8')
#bytes(str,encoding='utf-8')
md5_.update(value.encode('utf-8'))
#3.獲取加密內容
return md5_.hexdigest()
content = '''
User-Agent:客戶端請求標識。
cookie (cookie):在做登錄的時候需要封裝這個頭。
'''
print(get_hex(content)) # 881d8ddae168083dc2e4638f5ba27d65
(二)給一個文件進行加密
def get_file_hex(filename):
chunk_size = 1024
md5_ = hashlib.md5()
with open(filename,'r',encoding='utf-8') as fp:
chunk = fp.read(chunk_size)
if chunk:
md5_.update(bytes(chunk,encoding='utf-8'))
return md5_.hexdigest()
print(get_file_hex('01.txt')) # b4faaad91ae69258e1bdf95e7783318e