欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Python爬蟲原理與數(shù)據(jù)抓取

 更新時(shí)間:2020年07月21日 10:47:53   作者:luchun666  
這篇文章主要介紹了淺談爬蟲原理與數(shù)據(jù)抓取,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

通用爬蟲和聚焦爬蟲

根據(jù)使用場景,網(wǎng)絡(luò)爬蟲可分為通用爬蟲和聚焦爬蟲兩種.

通用爬蟲

通用網(wǎng)絡(luò)爬蟲 是 捜索引擎抓取系統(tǒng)(Baidu、Google、Yahoo等)的重要組成部分。主要目的是將互聯(lián)網(wǎng)上的網(wǎng)頁下載到本地,形成一個(gè)互聯(lián)網(wǎng)內(nèi)容的鏡像備份。

通用搜索引擎(Search Engine)工作原理

通用網(wǎng)絡(luò)爬蟲從互聯(lián)網(wǎng)中搜集網(wǎng)頁,采集信息,這些網(wǎng)頁信息用于為搜索引擎建立索引從而提供支持,它決定著整個(gè)引擎系統(tǒng)的內(nèi)容是否豐富,信息是否即時(shí),因此其性能的優(yōu)劣直接影響著搜索引擎的效果。

第一步:抓取網(wǎng)頁

搜索引擎網(wǎng)絡(luò)爬蟲的基本工作流程如下:

首先選取一部分的種子URL,將這些URL放入待抓取URL隊(duì)列;

取出待抓取URL,解析DNS得到主機(jī)的IP,并將URL對(duì)應(yīng)的網(wǎng)頁下載下來,存儲(chǔ)進(jìn)已下載網(wǎng)頁庫中,并且將這些URL放進(jìn)已抓取URL隊(duì)列。

分析已抓取URL隊(duì)列中的URL,分析其中的其他URL,并且將URL放入待抓取URL隊(duì)列,從而進(jìn)入下一個(gè)循環(huán)....

搜索引擎如何獲取一個(gè)新網(wǎng)站的URL:

1. 新網(wǎng)站向搜索引擎主動(dòng)提交網(wǎng)址:(如百度http://zhanzhang.baidu.com/linksubmit/url

2. 在其他網(wǎng)站上設(shè)置新網(wǎng)站外鏈(盡可能處于搜索引擎爬蟲爬取范圍)

3. 搜索引擎和DNS解析服務(wù)商(如DNSPod等)合作,新網(wǎng)站域名將被迅速抓取。

但是搜索引擎蜘蛛的爬行是被輸入了一定的規(guī)則的,它需要遵從一些命令或文件的內(nèi)容,如標(biāo)注為nofollow的鏈接,或者是Robots協(xié)議。

#Robots協(xié)議(也叫爬蟲協(xié)議、機(jī)器人協(xié)議等),全稱是“網(wǎng)絡(luò)爬蟲排除標(biāo)準(zhǔn)”(Robots Exclusion Protocol),網(wǎng)站通過Robots協(xié)議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取,例如:
淘寶網(wǎng):https://www.taobao.com/robots.txt
騰訊網(wǎng):http://www.qq.com/robots.txt

第二步:數(shù)據(jù)存儲(chǔ)

搜索引擎通過爬蟲爬取到的網(wǎng)頁,將數(shù)據(jù)存入原始頁面數(shù)據(jù)庫。其中的頁面數(shù)據(jù)與用戶瀏覽器得到的HTML是完全一樣的。

搜索引擎蜘蛛在抓取頁面時(shí),也做一定的重復(fù)內(nèi)容檢測,一旦遇到訪問權(quán)重很低的網(wǎng)站上有大量抄襲、采集或者復(fù)制的內(nèi)容,很可能就不再爬行。

第三步:預(yù)處理

搜索引擎將爬蟲抓取回來的頁面,進(jìn)行各種步驟的預(yù)處理。

提取文字中文分詞消除噪音(比如版權(quán)聲明文字、導(dǎo)航條、廣告等……)索引處理鏈接關(guān)系計(jì)算特殊文件處理....

除了HTML文件外,搜索引擎通常還能抓取和索引以文字為基礎(chǔ)的多種文件類型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。我們?cè)谒阉鹘Y(jié)果中也經(jīng)常會(huì)看到這些文件類型。

但搜索引擎還不能處理圖片、視頻、Flash 這類非文字內(nèi)容,也不能執(zhí)行腳本和程序。

第四步:提供檢索服務(wù),網(wǎng)站排名

搜索引擎在對(duì)信息進(jìn)行組織和處理后,為用戶提供關(guān)鍵字檢索服務(wù),將用戶檢索相關(guān)的信息展示給用戶。

同時(shí)會(huì)根據(jù)頁面的PageRank值(鏈接的訪問量排名)來進(jìn)行網(wǎng)站排名,這樣Rank值高的網(wǎng)站在搜索結(jié)果中會(huì)排名較前,當(dāng)然也可以直接使用 Money 購買搜索引擎網(wǎng)站排名,簡單粗暴。

但是,這些通用性搜索引擎也存在著一定的局限性:

通用搜索引擎所返回的結(jié)果都是網(wǎng)頁,而大多情況下,網(wǎng)頁里90%的內(nèi)容對(duì)用戶來說都是無用的。

不同領(lǐng)域、不同背景的用戶往往具有不同的檢索目的和需求,搜索引擎無法提供針對(duì)具體某個(gè)用戶的搜索結(jié)果。

萬維網(wǎng)數(shù)據(jù)形式的豐富和網(wǎng)絡(luò)技術(shù)的不斷發(fā)展,圖片、數(shù)據(jù)庫、音頻、視頻多媒體等不同數(shù)據(jù)大量出現(xiàn),通用搜索引擎對(duì)這些文件無能為力,不能很好地發(fā)現(xiàn)和獲取。

通用搜索引擎大多提供基于關(guān)鍵字的檢索,難以支持根據(jù)語義信息提出的查詢,無法準(zhǔn)確理解用戶的具體需求。

針對(duì)這些情況,聚焦爬蟲技術(shù)得以廣泛使用。

聚焦爬蟲

聚焦爬蟲,是"面向特定主題需求"的一種網(wǎng)絡(luò)爬蟲程序,它與通用搜索引擎爬蟲的區(qū)別在于:聚焦爬蟲在實(shí)施網(wǎng)頁抓取時(shí)會(huì)對(duì)內(nèi)容進(jìn)行處理篩選,盡量保證只抓取與需求相關(guān)的網(wǎng)頁信息。

而我們今后要學(xué)習(xí)的,就是聚焦爬蟲。

HTTP和HTTPS

HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議):是一種發(fā)布和接收 HTML頁面的方法。

HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下加入SSL層。

SSL(Secure Sockets Layer 安全套接層)主要用于Web的安全傳輸協(xié)議,在傳輸層對(duì)網(wǎng)絡(luò)連接進(jìn)行加密,保障在Internet上數(shù)據(jù)傳輸?shù)陌踩?/p>

HTTP的端口號(hào)為80,HTTPS的端口號(hào)為443

HTTP工作原理

網(wǎng)絡(luò)爬蟲抓取過程可以理解為模擬瀏覽器操作的過程。

瀏覽器的主要功能是向服務(wù)器發(fā)出請(qǐng)求,在瀏覽器窗口中展示您選擇的網(wǎng)絡(luò)資源,HTTP是一套計(jì)算機(jī)通過網(wǎng)絡(luò)進(jìn)行通信的規(guī)則。

HTTP的請(qǐng)求與響應(yīng)

HTTP通信由兩部分組成:客戶端請(qǐng)求消息與服務(wù)器響應(yīng)消息

瀏覽器發(fā)送HTTP請(qǐng)求的過程:

  1. 當(dāng)用戶在瀏覽器的地址欄中輸入一個(gè)URL并按回車鍵之后,瀏覽器會(huì)向HTTP服務(wù)器發(fā)送HTTP請(qǐng)求。HTTP請(qǐng)求主要分為“Get”和“Post”兩種方法。
  2. 當(dāng)我們?cè)跒g覽器輸入U(xiǎn)RLhttp://www.baidu.com的時(shí)候,瀏覽器發(fā)送一個(gè)Request請(qǐng)求去獲取http://www.baidu.com的html文件,服務(wù)器把Response文件對(duì)象發(fā)送回給瀏覽器。
  3. 瀏覽器分析Response中的 HTML,發(fā)現(xiàn)其中引用了很多其他文件,比如Images文件,CSS文件,JS文件。 瀏覽器會(huì)自動(dòng)再次發(fā)送Request去獲取圖片,CSS文件,或者JS文件。
  4. 當(dāng)所有的文件都下載成功后,網(wǎng)頁會(huì)根據(jù)HTML語法結(jié)構(gòu),完整的顯示出來了。

URL(Uniform / Universal Resource Locator的縮寫):統(tǒng)一資源定位符,是用于完整地描述Internet上網(wǎng)頁和其他資源的地址的一種標(biāo)識(shí)方法。

基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]

  • scheme:協(xié)議(例如:http, https, ftp)
  • host:服務(wù)器的IP地址或者域名
  • port#:服務(wù)器的端口(如果是走協(xié)議默認(rèn)端口,缺省端口80)
  • path:訪問資源的路徑
  • query-string:參數(shù),發(fā)送給http服務(wù)器的數(shù)據(jù)
  • anchor:錨(跳轉(zhuǎn)到網(wǎng)頁的指定錨點(diǎn)位置)

例如:

ftp://192.168.0.116:8080/index

http://www.baidu.com

http://item.jd.com/11936238.html

客戶端HTTP請(qǐng)求

URL只是標(biāo)識(shí)資源的位置,而HTTP是用來提交和獲取資源??蛻舳税l(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器的請(qǐng)求消息,包括以下格式:

請(qǐng)求行、請(qǐng)求頭部、空行、請(qǐng)求數(shù)據(jù)

四個(gè)部分組成,下圖給出了請(qǐng)求報(bào)文的一般格式。

一個(gè)典型的HTTP請(qǐng)求示例

GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://www.baidu.com/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: BAIDUID=04E4001F34EA74AD4601512DD3C41A7B:FG=1; BIDUPSID=04E4001F34EA74AD4601512DD3C41A7B; PSTM=1470329258

請(qǐng)求方法

GET https://www.baidu.com/ HTTP/1.1

根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。

HTTP 0.9:只有基本的文本 GET 功能。

HTTP 1.0:完善的請(qǐng)求/響應(yīng)模型,并將協(xié)議補(bǔ)充完整,定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。

HTTP 1.1:在 1.0 基礎(chǔ)上進(jìn)行更新,新增了五種請(qǐng)求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

HTTP 2.0(未普及):請(qǐng)求/響應(yīng)首部的定義基本沒有改變,只是所有首部鍵必須全部小寫,而且請(qǐng)求行要獨(dú)立為 :method、:scheme、:host、:path這些鍵值對(duì)。

序號(hào) 方法 描述
1 GET 請(qǐng)求指定的頁面信息,并返回實(shí)體主體。
2 HEAD 類似于get請(qǐng)求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報(bào)頭
3 POST 向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(例如提交表單或者上傳文件),數(shù)據(jù)被包含在請(qǐng)求體中。POST請(qǐng)求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改。
4 PUT 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。
5 DELETE 請(qǐng)求服務(wù)器刪除指定的頁面。
6 CONNECT HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。
7 OPTIONS 允許客戶端查看服務(wù)器的性能。
8 TRACE 回顯服務(wù)器收到的請(qǐng)求,主要用于測試或診斷。

HTTP請(qǐng)求主要分為Get和Post兩種方法

  • GET是從服務(wù)器上獲取數(shù)據(jù),POST是向服務(wù)器傳送數(shù)據(jù)
  • GET請(qǐng)求參數(shù)顯示,都顯示在瀏覽器網(wǎng)址上,HTTP服務(wù)器根據(jù)該請(qǐng)求所包含URL中的參數(shù)來產(chǎn)生響應(yīng)內(nèi)容,即“Get”請(qǐng)求的參數(shù)是URL的一部分。 例如:http://www.baidu.com/s?wd=Chinese
  • POST請(qǐng)求參數(shù)在請(qǐng)求體當(dāng)中,消息長度沒有限制而且以隱式的方式進(jìn)行發(fā)送,通常用來向HTTP服務(wù)器提交量比較大的數(shù)據(jù)(比如請(qǐng)求中包含許多參數(shù)或者文件上傳操作等),請(qǐng)求的參數(shù)包含在“Content-Type”消息頭里,指明該消息體的媒體類型和編碼,

注意:避免使用Get方式提交表單,因?yàn)橛锌赡軙?huì)導(dǎo)致安全問題。 比如說在登陸表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。

常用的請(qǐng)求報(bào)頭

1. Host (主機(jī)和端口號(hào))

Host:對(duì)應(yīng)網(wǎng)址URL中的Web名稱和端口號(hào),用于指定被請(qǐng)求資源的Internet主機(jī)和端口號(hào),通常屬于URL的一部分。

2. Connection (鏈接類型)

Connection:表示客戶端與服務(wù)連接類型

Client 發(fā)起一個(gè)包含Connection:keep-alive的請(qǐng)求,HTTP/1.1使用keep-alive為默認(rèn)值。

Server收到請(qǐng)求后:

如果 Server 支持 keep-alive,回復(fù)一個(gè)包含 Connection:keep-alive 的響應(yīng),不關(guān)閉連接;如果 Server 不支持 keep-alive,回復(fù)一個(gè)包含 Connection:close 的響應(yīng),關(guān)閉連接。

如果client收到包含Connection:keep-alive的響應(yīng),向同一個(gè)連接發(fā)送下一個(gè)請(qǐng)求,直到一方主動(dòng)關(guān)閉連接。

keep-alive在很多情況下能夠重用連接,減少資源消耗,縮短響應(yīng)時(shí)間,比如當(dāng)瀏覽器需要多個(gè)文件時(shí)(比如一個(gè)HTML文件和相關(guān)的圖形文件),不需要每次都去請(qǐng)求建立連接。

3. Upgrade-Insecure-Requests (升級(jí)為HTTPS請(qǐng)求)

Upgrade-Insecure-Requests:升級(jí)不安全的請(qǐng)求,意思是會(huì)在加載 http 資源時(shí)自動(dòng)替換成 https 請(qǐng)求,讓瀏覽器不再顯示https頁面中的http請(qǐng)求警報(bào)。

HTTPS 是以安全為目標(biāo)的 HTTP 通道,所以在 HTTPS 承載的頁面上不允許出現(xiàn) HTTP 請(qǐng)求,一旦出現(xiàn)就是提示或報(bào)錯(cuò)。

4. User-Agent (瀏覽器名稱)

User-Agent:是客戶瀏覽器的名稱,以后會(huì)詳細(xì)講。

5. Accept (傳輸文件類型)

Accept:指瀏覽器或其他客戶端可以接受的MIME(Multipurpose Internet Mail Extensions(多用途互聯(lián)網(wǎng)郵件擴(kuò)展))文件類型,服務(wù)器可以根據(jù)它判斷并返回適當(dāng)?shù)奈募袷健?/p>

舉例:

Accept: */*:表示什么都可以接收。

Accept:image/gif:表明客戶端希望接受GIF圖像格式的資源;

Accept:text/html:表明客戶端希望接受html文本。

Accept: text/html, application/xhtml+xml;q=0.9, image/*;q=0.8:表示瀏覽器支持的 MIME 類型分別是 html文本、xhtml和xml文檔、所有的圖像格式資源。

q是權(quán)重系數(shù),范圍 0 =< q <= 1,q 值越大,請(qǐng)求越傾向于獲得其“;”之前的類型表示的內(nèi)容。若沒有指定q值,則默認(rèn)為1,按從左到右排序順序;若被賦值為0,則用于表示瀏覽器不接受此內(nèi)容類型。

Text:用于標(biāo)準(zhǔn)化地表示的文本信息,文本消息可以是多種字符集和或者多種格式的;Application:用于傳輸應(yīng)用程序數(shù)據(jù)或者二進(jìn)制數(shù)據(jù)。

6. Referer (頁面跳轉(zhuǎn)處)

Referer:表明產(chǎn)生請(qǐng)求的網(wǎng)頁來自于哪個(gè)URL,用戶是從該 Referer頁面訪問到當(dāng)前請(qǐng)求的頁面。這個(gè)屬性可以用來跟蹤Web請(qǐng)求來自哪個(gè)頁面,是從什么網(wǎng)站來的等。

有時(shí)候遇到下載某網(wǎng)站圖片,需要對(duì)應(yīng)的referer,否則無法下載圖片,那是因?yàn)槿思易隽朔辣I鏈,原理就是根據(jù)referer去判斷是否是本網(wǎng)站的地址,如果不是,則拒絕,如果是,就可以下載;

7. Accept-Encoding(文件編解碼格式)

Accept-Encoding:指出瀏覽器可以接受的編碼方式。編碼方式不同于文件格式,它是為了壓縮文件并加速文件傳遞速度。瀏覽器在接收到Web響應(yīng)之后先解碼,然后再檢查文件格式,許多情形下這可以減少大量的下載時(shí)間。

舉例:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0

如果有多個(gè)Encoding同時(shí)匹配, 按照q值順序排列,本例中按順序支持 gzip, identity壓縮編碼,支持gzip的瀏覽器會(huì)返回經(jīng)過gzip編碼的HTML頁面。如果請(qǐng)求消息中沒有設(shè)置這個(gè)域服務(wù)器假定客戶端對(duì)各種內(nèi)容編碼都可以接受。

8. Accept-Language(語言種類)

Accept-Langeuage:指出瀏覽器可以接受的語言種類,如en或en-us指英語,zh或者zh-cn指中文,當(dāng)服務(wù)器能夠提供一種以上的語言版本時(shí)要用到。

9. Accept-Charset(字符編碼)

Accept-Charset:指出瀏覽器可以接受的字符編碼。

舉例:Accept-Charset:iso-8859-1,gb2312,utf-8ISO8859-1:通常叫做Latin-1。Latin-1包括了書寫所有西方歐洲語言不可缺少的附加字符,英文瀏覽器的默認(rèn)值是ISO-8859-1.gb2312:標(biāo)準(zhǔn)簡體中文字符集;utf-8:UNICODE 的一種變長字符編碼,可以解決多種語言文本顯示問題,從而實(shí)現(xiàn)應(yīng)用國際化和本地化。

如果在請(qǐng)求消息中沒有設(shè)置這個(gè)域,缺省是任何字符集都可以接受。

10. Cookie (Cookie)

Cookie:瀏覽器用這個(gè)屬性向服務(wù)器發(fā)送Cookie。Cookie是在瀏覽器中寄存的小型數(shù)據(jù)體,它可以記載和服務(wù)器相關(guān)的用戶信息,也可以用來實(shí)現(xiàn)會(huì)話功能,以后會(huì)詳細(xì)講。

11. Content-Type (POST數(shù)據(jù)類型)

Content-Type:POST請(qǐng)求里用來表示的內(nèi)容類型。

舉例:Content-Type = Text/XML; charset=gb2312:

指明該請(qǐng)求的消息體中包含的是純文本的XML類型的數(shù)據(jù),字符編碼采用“gb2312”。

服務(wù)端HTTP響應(yīng)

HTTP響應(yīng)也由四個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、空行、響應(yīng)正文

HTTP/1.1 200 OK
Server: Tengine
Connection: keep-alive
Date: Wed, 30 Nov 2016 07:58:21 GMT
Cache-Control: no-cache
Content-Type: text/html;charset=UTF-8
Keep-Alive: timeout=20
Vary: Accept-Encoding
Pragma: no-cache
X-NWS-LOG-UUID: bd27210a-24e5-4740-8f6c-25dbafa9c395
Content-Length: 180945

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ....

常用的響應(yīng)報(bào)頭(了解)

理論上所有的響應(yīng)頭信息都應(yīng)該是回應(yīng)請(qǐng)求頭的。但是服務(wù)端為了效率,安全,還有其他方面的考慮,會(huì)添加相對(duì)應(yīng)的響應(yīng)頭信息,從上圖可以看到:

1. Cache-Control:must-revalidate, no-cache, private。

這個(gè)值告訴客戶端,服務(wù)端不希望客戶端緩存資源,在下次請(qǐng)求資源時(shí),必須要從新請(qǐng)求服務(wù)器,不能從緩存副本中獲取資源。

Cache-Control是響應(yīng)頭中很重要的信息,當(dāng)客戶端請(qǐng)求頭中包含Cache-Control:max-age=0請(qǐng)求,明確表示不會(huì)緩存服務(wù)器資源時(shí),Cache-Control作為作為回應(yīng)信息,通常會(huì)返回no-cache,意思就是說,"那就不緩存唄"。

當(dāng)客戶端在請(qǐng)求頭中沒有包含Cache-Control時(shí),服務(wù)端往往會(huì)定,不同的資源不同的緩存策略,比如說oschina在緩存圖片資源的策略就是Cache-Control:max-age=86400,這個(gè)意思是,從當(dāng)前時(shí)間開始,在86400秒的時(shí)間內(nèi),客戶端可以直接從緩存副本中讀取資源,而不需要向服務(wù)器請(qǐng)求。

2. Connection:keep-alive

這個(gè)字段作為回應(yīng)客戶端的Connection:keep-alive,告訴客戶端服務(wù)器的tcp連接也是一個(gè)長連接,客戶端可以繼續(xù)使用這個(gè)tcp連接發(fā)送http請(qǐng)求。

3. Content-Encoding:gzip

告訴客戶端,服務(wù)端發(fā)送的資源是采用gzip編碼的,客戶端看到這個(gè)信息后,應(yīng)該采用gzip對(duì)資源進(jìn)行解碼。

4. Content-Type:text/html;charset=UTF-8

告訴客戶端,資源文件的類型,還有字符編碼,客戶端通過utf-8對(duì)資源進(jìn)行解碼,然后對(duì)資源進(jìn)行html解析。通常我們會(huì)看到有些網(wǎng)站是亂碼的,往往就是服務(wù)器端沒有返回正確的編碼。

5. Date:Sun, 21 Sep 2016 06:18:21 GMT

這個(gè)是服務(wù)端發(fā)送資源時(shí)的服務(wù)器時(shí)間,GMT是格林尼治所在地的標(biāo)準(zhǔn)時(shí)間。http協(xié)議中發(fā)送的時(shí)間都是GMT的,這主要是解決在互聯(lián)網(wǎng)上,不同時(shí)區(qū)在相互請(qǐng)求資源的時(shí)候,時(shí)間混亂問題。

6. Expires:Sun, 1 Jan 2000 01:00:00 GMT

這個(gè)響應(yīng)頭也是跟緩存有關(guān)的,告訴客戶端在這個(gè)時(shí)間前,可以直接訪問緩存副本,很顯然這個(gè)值會(huì)存在問題,因?yàn)榭蛻舳撕头?wù)器的時(shí)間不一定會(huì)都是相同的,如果時(shí)間不同就會(huì)導(dǎo)致問題。所以這個(gè)響應(yīng)頭是沒有Cache-Control:max-age=*這個(gè)響應(yīng)頭準(zhǔn)確的,因?yàn)閙ax-age=date中的date是個(gè)相對(duì)時(shí)間,不僅更好理解,也更準(zhǔn)確。

7. Pragma:no-cache

這個(gè)含義與Cache-Control等同。

8.Server:Tengine/1.4.6

這個(gè)是服務(wù)器和相對(duì)應(yīng)的版本,只是告訴客戶端服務(wù)器的信息。

9. Transfer-Encoding:chunked

這個(gè)響應(yīng)頭告訴客戶端,服務(wù)器發(fā)送的資源的方式是分塊發(fā)送的。一般分塊發(fā)送的資源都是服務(wù)器動(dòng)態(tài)生成的,在發(fā)送時(shí)還不知道發(fā)送資源的大小,所以采用分塊發(fā)送,每一塊都是獨(dú)立的,獨(dú)立的塊都能標(biāo)示自己的長度,最后一塊是0長度的,當(dāng)客戶端讀到這個(gè)0長度的塊時(shí),就可以確定資源已經(jīng)傳輸完了。

10. Vary: Accept-Encoding

告訴緩存服務(wù)器,緩存壓縮文件和非壓縮文件兩個(gè)版本,現(xiàn)在這個(gè)字段用處并不大,因?yàn)楝F(xiàn)在的瀏覽器都是支持壓縮的。

響應(yīng)狀態(tài)碼

響應(yīng)狀態(tài)代碼有三位數(shù)字組成,第一個(gè)數(shù)字定義了響應(yīng)的類別,且有五種可能取值。

常見狀態(tài)碼:

100~199:表示服務(wù)器成功接收部分請(qǐng)求,要求客戶端繼續(xù)提交其余請(qǐng)求才能完成整個(gè)處理過程。

200~299:表示服務(wù)器成功接收請(qǐng)求并已完成整個(gè)處理過程。常用200(OK 請(qǐng)求成功)。

300~399:為完成請(qǐng)求,客戶需進(jìn)一步細(xì)化請(qǐng)求。例如:請(qǐng)求的資源已經(jīng)移動(dòng)一個(gè)新地址、常用302(所請(qǐng)求的頁面已經(jīng)臨時(shí)轉(zhuǎn)移至新的url)、307和304(使用緩存資源)。400~499:客戶端的請(qǐng)求有錯(cuò)誤,常用404(服務(wù)器無法找到被請(qǐng)求的頁面)、403(服務(wù)器拒絕訪問,權(quán)限不夠)。500~599:服務(wù)器端出現(xiàn)錯(cuò)誤,常用500(請(qǐng)求未完成。服務(wù)器遇到不可預(yù)知的情況)。

Cookie 和 Session:

服務(wù)器和客戶端的交互僅限于請(qǐng)求/響應(yīng)過程,結(jié)束之后便斷開,在下一次請(qǐng)求時(shí),服務(wù)器會(huì)認(rèn)為新的客戶端。

為了維護(hù)他們之間的鏈接,讓服務(wù)器知道這是前一個(gè)用戶發(fā)送的請(qǐng)求,必須在一個(gè)地方保存客戶端的信息。

Cookie:通過在 客戶端 記錄的信息確定用戶的身份。

Session:通過在 服務(wù)器端 記錄的信息確定用戶的身份。

Fiddler界面

設(shè)置好后,本機(jī)HTTP通信都會(huì)經(jīng)過127.0.0.1:8888代理,也就會(huì)被Fiddler攔截到。

請(qǐng)求 (Request) 部分詳解

  1. Headers —— 顯示客戶端發(fā)送到服務(wù)器的 HTTP 請(qǐng)求的 header,顯示為一個(gè)分級(jí)視圖,包含了 Web 客戶端信息、Cookie、傳輸狀態(tài)等。
  2. Textview —— 顯示 POST 請(qǐng)求的 body 部分為文本。
  3. WebForms —— 顯示請(qǐng)求的 GET 參數(shù) 和 POST body 內(nèi)容。
  4. HexView —— 用十六進(jìn)制數(shù)據(jù)顯示請(qǐng)求。
  5. Auth —— 顯示響應(yīng) header 中的 Proxy-Authorization(代理身份驗(yàn)證) 和 Authorization(授權(quán)) 信息.
  6. Raw —— 將整個(gè)請(qǐng)求顯示為純文本。
  7. JSON - 顯示JSON格式文件。
  8. XML —— 如果請(qǐng)求的 body 是 XML 格式,就是用分級(jí)的 XML 樹來顯示它。

響應(yīng) (Response) 部分詳解

  1. Transformer —— 顯示響應(yīng)的編碼信息。
  2. Headers —— 用分級(jí)視圖顯示響應(yīng)的 header。
  3. TextView —— 使用文本顯示相應(yīng)的 body。
  4. ImageVies —— 如果請(qǐng)求是圖片資源,顯示響應(yīng)的圖片。
  5. HexView —— 用十六進(jìn)制數(shù)據(jù)顯示響應(yīng)。
  6. WebView —— 響應(yīng)在 Web 瀏覽器中的預(yù)覽效果。
  7. Auth —— 顯示響應(yīng) header 中的 Proxy-Authorization(代理身份驗(yàn)證) 和 Authorization(授權(quán)) 信息。
  8. Caching —— 顯示此請(qǐng)求的緩存信息。
  9. Privacy —— 顯示此請(qǐng)求的私密 (P3P) 信息。
  10. Raw —— 將整個(gè)響應(yīng)顯示為純文本。
  11. JSON - 顯示JSON格式文件。
  12. XML —— 如果響應(yīng)的 body 是 XML 格式,就是用分級(jí)的 XML 樹來顯示它 。

HTTP/HTTPS的GET和POST方法

urllib.parse.urlencode()

# IPython 中的測試結(jié)果
In [1]: import urllib.parse

In [2]: word = {"wd" : "傳智播客"}

# 通過urllib.parse.urlencode()方法,將字典鍵值對(duì)按URL編碼轉(zhuǎn)換,從而能被web服務(wù)器接受。
In [3]: urllib..parse.urlencode(word) 
Out[3]: "wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2"

# 通過urllib.parse.unquote()方法,把 URL編碼字符串,轉(zhuǎn)換回原先字符串。
In [4]: print (urllib.parse.unquote("wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2"))
wd=傳智播客

一般HTTP請(qǐng)求提交數(shù)據(jù),需要編碼成 URL編碼格式,然后做為url的一部分,或者作為參數(shù)傳到Request對(duì)象中。

Get方式

GET請(qǐng)求一般用于我們向服務(wù)器獲取數(shù)據(jù),比如說,我們用百度搜索傳智播客:https://www.baidu.com/s?wd=傳智播客

瀏覽器的url會(huì)跳轉(zhuǎn)成如圖所示:

https://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2

在其中我們可以看到在請(qǐng)求部分里,http://www.baidu.com/s?之后出現(xiàn)一個(gè)長長的字符串,其中就包含我們要查詢的關(guān)鍵詞傳智播客,于是我們可以嘗試用默認(rèn)的Get方式來發(fā)送請(qǐng)求。

# urllib_get.py

import urllib.parse #負(fù)責(zé)url編碼處理
import urllib.request

url = "http://www.baidu.com/s"
word = {"wd":"傳智播客"}
word = urllib.parse.urlencode(word) #轉(zhuǎn)換成url編碼格式(字符串)
newurl = url + "?" + word # url首個(gè)分隔符就是 ?

headers={ "User-Agent": "
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36
"} 
request = urllib.request.Request(newurl, headers=headers) 
response = urllib.request.urlopen(request) 

print (response.read()) 

批量爬取貼吧頁面數(shù)據(jù)

首先我們創(chuàng)建一個(gè)python文件, tiebaSpider.py,我們要完成的是,輸入一個(gè)百度貼吧的地址,比如:

百度貼吧LOL吧第一頁:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0

第二頁:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50

第三頁:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100

發(fā)現(xiàn)規(guī)律了吧,貼吧中每個(gè)頁面不同之處,就是url最后的pn的值,其余的都是一樣的,我們可以抓住這個(gè)規(guī)律。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib.request
import urllib.parse

def loadPage(url, filename):
 """
 作用:根據(jù)url發(fā)送請(qǐng)求,獲取服務(wù)器響應(yīng)文件
 url: 需要爬取的url地址
 filename : 處理的文件名
 """
 print ("正在下載 " + filename)
 headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36"}

 request = urllib.request.Request(url, headers = headers)
 return urllib.request.urlopen(request).read()

def writePage(html, filename):
 """
 作用:將html內(nèi)容寫入到本地
 html:服務(wù)器相應(yīng)文件內(nèi)容
 """
 print ("正在保存 " + filename)
 # 文件寫入
 with open(filename, "wb+") as f:
 f.write(html)
 print ("-" * 30)

def tiebaSpider(url, beginPage, endPage):
 """
 作用:貼吧爬蟲調(diào)度器,負(fù)責(zé)組合處理每個(gè)頁面的url
 url : 貼吧url的前部分
 beginPage : 起始頁
 endPage : 結(jié)束頁
 """
 for page in range(beginPage, endPage + 1):
 pn = (page - 1) * 50
 filename = "第" + str(page) + "頁.html"
 fullurl = url + "&pn=" + str(pn)
 #print fullurl
 html = loadPage(fullurl, filename)
 #print html
 writePage(html, filename)
 print ('謝謝使用')

if __name__ == "__main__":
 kw = input("請(qǐng)輸入需要爬取的貼吧名:")
 beginPage = int(input("請(qǐng)輸入起始頁:"))
 endPage = int(input("請(qǐng)輸入結(jié)束頁:"))

 url = "http://tieba.baidu.com/f?"
 key = urllib.parse.urlencode({"kw": kw})
 fullurl = url + key
 tiebaSpider(fullurl, beginPage, endPage)

其實(shí)很多網(wǎng)站都是這樣的,同類網(wǎng)站下的html頁面編號(hào),分別對(duì)應(yīng)網(wǎng)址后的網(wǎng)頁序號(hào),只要發(fā)現(xiàn)規(guī)律就可以批量爬取頁面了。

POST方式:

上面我們說了Request請(qǐng)求對(duì)象的里有data參數(shù),它就是用在POST里的,我們要傳送的數(shù)據(jù)就是這個(gè)參數(shù)data,data是一個(gè)字典,里面要匹配鍵值對(duì)。

有道詞典翻譯網(wǎng)站:

輸入測試數(shù)據(jù),再通過使用Fiddler觀察,其中有一條是POST請(qǐng)求,而向服務(wù)器發(fā)送的請(qǐng)求數(shù)據(jù)并不是在url里,那么我們可以試著模擬這個(gè)POST請(qǐng)求。

于是,我們可以嘗試用POST方式發(fā)送請(qǐng)求。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib.request
import urllib.parse

# 通過抓包的方式獲取的url,并不是瀏覽器上顯示的url
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null"

# 完整的headers
headers = {
 "Accept" : "application/json, text/javascript, */*; q=0.01",
 "X-Requested-With" : "XMLHttpRequest",
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36",
 "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
 }

# 用戶接口輸入

# 發(fā)送到web服務(wù)器的表單數(shù)據(jù)
formdata = {
"type" : "AUTO",
"i" : "我愛你",
"doctype" : "json",
"xmlVersion" : "1.6",
"keyfrom" : "fanyi.web",
"ue" : "UTF-8",
"typoResult" : "true"
}

# 經(jīng)過urlencode轉(zhuǎn)碼
data = urllib.parse.urlencode(formdata).encode('utf-8')

# 如果Request()方法里的data參數(shù)有值,那么這個(gè)請(qǐng)求就是POST
# 如果沒有,就是Get
#request = urllib.request.Request(url, data = data, headers = headers)
response = urllib.request.urlopen(url,data)

html = response.read().decode('utf-8')

print(html)
#print (urllib.request.urlopen(req).read())

發(fā)送POST請(qǐng)求時(shí),需要特別注意headers的一些屬性:

Content-Length: 144: 是指發(fā)送的表單數(shù)據(jù)長度為144,也就是字符個(gè)數(shù)是144個(gè)。

X-Requested-With: XMLHttpRequest:表示Ajax異步請(qǐng)求。

Content-Type: application/x-www-form-urlencoded: 表示瀏覽器提交 Web 表單時(shí)使用,表單數(shù)據(jù)會(huì)按照name1=value1&name2=value2鍵值對(duì)形式進(jìn)行編碼。

獲取AJAX加載的內(nèi)容

有些網(wǎng)頁內(nèi)容使用AJAX加載,只要記得,AJAX一般返回的是JSON,直接對(duì)AJAX地址進(jìn)行post或get,就返回JSON數(shù)據(jù)了。

"作為一名爬蟲工程師,你最需要關(guān)注的,是數(shù)據(jù)的來源"

import urllib
import urllib2

# demo1

url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action"

headers={"User-Agent": "Mozilla...."}

# 變動(dòng)的是這兩個(gè)參數(shù),從start開始往后顯示limit個(gè)
formdata = {
 'start':'0',
 'limit':'10'
}
data = urllib.urlencode(formdata)

request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)

print response.read()


# demo2

url = "https://movie.douban.com/j/chart/top_list?"
headers={"User-Agent": "Mozilla...."}

# 處理所有參數(shù)
formdata = {
 'type':'11',
 'interval_id':'100:90',
 'action':'',
 'start':'0',
 'limit':'10'
}
data = urllib.urlencode(formdata)

request = urllib2.Request(url, data = data, headers = headers)
response = urllib2.urlopen(request)

print response.read()

問題:為什么有時(shí)候POST也能在URL內(nèi)看到數(shù)據(jù)?

  • GET方式是直接以鏈接形式訪問,鏈接中包含了所有的參數(shù),服務(wù)器端用Request.QueryString獲取變量的值。如果包含了密碼的話是一種不安全的選擇,不過你可以直觀地看到自己提交了什么內(nèi)容。
  • POST則不會(huì)在網(wǎng)址上顯示所有的參數(shù),服務(wù)器端用Request.Form獲取提交的數(shù)據(jù),在Form提交的時(shí)候。但是HTML代碼里如果不指定 method 屬性,則默認(rèn)為GET請(qǐng)求,F(xiàn)orm中提交的數(shù)據(jù)將會(huì)附加在url之后,以?分開與url分開。
  • 表單數(shù)據(jù)可以作為 URL 字段(method="get")或者 HTTP POST (method="post")的方式來發(fā)送。比如在下面的HTML代碼中,表單數(shù)據(jù)將因?yàn)?(method="get") 而附加到 URL 上:
<form action="form_action.asp" method="get">
 <p>First name: <input type="text" name="fname" /></p>
 <p>Last name: <input type="text" name="lname" /></p>
 <input type="submit" value="Submit" />
</form>

利用cookie模擬登陸

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib.request

url = "http://www.renren.com/410043129/profile"

headers = {
 "Host" : "www.renren.com",
 "Connection" : "keep-alive",
 #"Upgrade-Insecure-Requests" : "1",
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
 "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
 "Referer" : "http://www.renren.com/SysHome.do",
 #"Accept-Encoding" : "gzip, deflate, sdch",#加上會(huì)得到壓縮文件
 "Cookie" : "anonymid=ixrna3fysufnwv; _r01_=1; depovince=GW; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484400895379; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484400890914; JSESSIONID=abcX8s_OqSGsYeRg5vHMv; jebecookies=0c5f9b0d-03d8-4e6a-b7a9-3845d04a9870|||||; ick_login=8a429d6c-78b4-4e79-8fd5-33323cd9e2bc; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; p=0cedb18d0982741d12ffc9a0d93670e09; ap=327550029; first_login_flag=1; ln_uact=mr_mao_hacker@163.com; ln_hurl=http://hdn.xnimg.cn/photos/hdn521/20140529/1055/h_main_9A3Z_e0c300019f6a195a.jpg; t=56c0c522b5b068fdee708aeb1056ee819; societyguester=56c0c522b5b068fdee708aeb1056ee819; id=327550029; xnsid=5ea75bd6; loginfrom=syshome",
 "Accept-Language" : "zh-CN,zh;q=0.8,en;q=0.6",
}

request = urllib.request.Request(url, headers = headers)

response = urllib.request.urlopen(request)

print(response.read())

處理HTTPS請(qǐng)求 SSL證書驗(yàn)證

現(xiàn)在隨處可見 https 開頭的網(wǎng)站,urllib2可以為 HTTPS 請(qǐng)求驗(yàn)證SSL證書,就像web瀏覽器一樣,如果網(wǎng)站的SSL證書是經(jīng)過CA認(rèn)證的,則能夠正常訪問,如:https://www.baidu.com/等...

如果SSL證書驗(yàn)證不通過,或者操作系統(tǒng)不信任服務(wù)器的安全證書,比如瀏覽器在訪問12306網(wǎng)站如:https://www.12306.cn/mormhweb/的時(shí)候,會(huì)警告用戶證書不受信任。(據(jù)說 12306 網(wǎng)站證書是自己做的,沒有通過CA認(rèn)證)

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib.request
import ssl

# 忽略SSL安全認(rèn)證
context = ssl._create_unverified_context()

url = "https://www.12306.cn/mormhweb/"
#url = "https://www.baidu.com/"

headers = {
 "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"
 }
request = urllib.request.Request(url, headers = headers)

# 添加到context參數(shù)里
response = urllib.request.urlopen(request, context = context)

print (response.read())

關(guān)于CA

CA(Certificate Authority)是數(shù)字證書認(rèn)證中心的簡稱,是指發(fā)放、管理、廢除數(shù)字證書的受信任的第三方機(jī)構(gòu),如北京數(shù)字認(rèn)證股份有限公司、上海市數(shù)字證書認(rèn)證中心有限公司等...

CA的作用是檢查證書持有者身份的合法性,并簽發(fā)證書,以防證書被偽造或篡改,以及對(duì)證書和密鑰進(jìn)行管理。

現(xiàn)實(shí)生活中可以用身份證來證明身份, 那么在網(wǎng)絡(luò)世界里,數(shù)字證書就是身份證。和現(xiàn)實(shí)生活不同的是,并不是每個(gè)上網(wǎng)的用戶都有數(shù)字證書的,往往只有當(dāng)一個(gè)人需要證明自己的身份的時(shí)候才需要用到數(shù)字證書。

普通用戶一般是不需要,因?yàn)榫W(wǎng)站并不關(guān)心是誰訪問了網(wǎng)站,現(xiàn)在的網(wǎng)站只關(guān)心流量。但是反過來,網(wǎng)站就需要證明自己的身份了。

比如說現(xiàn)在釣魚網(wǎng)站很多的,比如你想訪問的是www.baidu.com,但其實(shí)你訪問的是www.daibu.com”,所以在提交自己的隱私信息之前需要驗(yàn)證一下網(wǎng)站的身份,要求網(wǎng)站出示數(shù)字證書。

一般正常的網(wǎng)站都會(huì)主動(dòng)出示自己的數(shù)字證書,來確??蛻舳撕途W(wǎng)站服務(wù)器之間的通信數(shù)據(jù)是加密安全的。

到此這篇關(guān)于淺談爬蟲原理與數(shù)據(jù)抓取的文章就介紹到這了,更多相關(guān)爬蟲原理 數(shù)據(jù)抓取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論