通用爬蟲和聚焦爬蟲
根據使用場景,網絡爬蟲可分爲 通用爬蟲 和 聚焦爬蟲 兩種.javascript
通用爬蟲
通用網絡爬蟲 是 捜索引擎抓取系統(Baidu、Google、Yahoo等)的重要組成部分。主要目的是將互聯網上的網頁下載到本地,造成一個互聯網內容的鏡像備份。html
通用搜索引擎(Search Engine)工做原理
通用網絡爬蟲 從互聯網中搜集網頁,採集信息,這些網頁信息用於爲搜索引擎創建索引從而提供支持,它決定着整個引擎系統的內容是否豐富,信息是否即時,所以其性能的優劣直接影響着搜索引擎的效果。java
第一步:抓取網頁
搜索引擎網絡爬蟲的基本工做流程以下:python
首先選取一部分的種子URL,將這些URL放入待抓取URL隊列;web
取出待抓取URL,解析DNS獲得主機的IP,並將URL對應的網頁下載下來,存儲進已下載網頁庫中,而且將這些URL放進已抓取URL隊列。數據庫
分析已抓取URL隊列中的URL,分析其中的其餘URL,而且將URL放入待抓取URL隊列,從而進入下一個循環....json
搜索引擎如何獲取一個新網站的URL:瀏覽器
可是搜索引擎蜘蛛的爬行是被輸入了必定的規則的,它須要聽從一些命令或文件的內容,如標註爲nofollow的連接,或者是Robots協議。緩存
Robots協議(也叫爬蟲協議、機器人協議等),全稱是「網絡爬蟲排除標準」(Robots Exclusion Protocol),網站經過Robots協議告訴搜索引擎哪些頁面能夠抓取,哪些頁面不能抓取,例如:安全
淘寶網:https://www.taobao.com/robots...
騰訊網: http://www.qq.com/robots.txt
第二步:數據存儲
搜索引擎經過爬蟲爬取到的網頁,將數據存入原始頁面數據庫。其中的頁面數據與用戶瀏覽器獲得的HTML是徹底同樣的。
搜索引擎蜘蛛在抓取頁面時,也作必定的重複內容檢測,一旦遇到訪問權重很低的網站上有大量抄襲、採集或者複製的內容,極可能就再也不爬行。
第三步:預處理
搜索引擎將爬蟲抓取回來的頁面,進行各類步驟的預處理。
提取文字
中文分詞
消除噪音(好比版權聲明文字、導航條、廣告等……)
索引處理
連接關係計算
特殊文件處理
....
除了HTML文件外,搜索引擎一般還能抓取和索引以文字爲基礎的多種文件類型,如 PDF、Word、WPS、XLS、PPT、TXT 文件等。咱們在搜索結果中也常常會看到這些文件類型。
但搜索引擎還不能處理圖片、視頻、Flash 這類非文字內容,也不能執行腳本和程序。
第四步:提供檢索服務,網站排名
搜索引擎在對信息進行組織和處理後,爲用戶提供關鍵字檢索服務,將用戶檢索相關的信息展現給用戶。
同時會根據頁面的PageRank值(連接的訪問量排名)來進行網站排名,這樣Rank值高的網站在搜索結果中會排名較前,固然也能夠直接使用 Money 購買搜索引擎網站排名,簡單粗暴。
可是,這些通用性搜索引擎也存在着必定的侷限性:
通用搜索引擎所返回的結果都是網頁,而大多狀況下,網頁裏90%的內容對用戶來講都是無用的。
不一樣領域、不一樣背景的用戶每每具備不一樣的檢索目的和需求,搜索引擎沒法提供針對具體某個用戶的搜索結果。
萬維網數據形式的豐富和網絡技術的不斷髮展,圖片、數據庫、音頻、視頻多媒體等不一樣數據大量出現,通用搜索引擎對這些文件無能爲力,不能很好地發現和獲取。
通用搜索引擎大多提供基於關鍵字的檢索,難以支持根據語義信息提出的查詢,沒法準確理解用戶的具體需求。
針對這些狀況,聚焦爬蟲技術得以普遍使用。
聚焦爬蟲
聚焦爬蟲,是"面向特定主題需求"的一種網絡爬蟲程序,它與通用搜索引擎爬蟲的區別在於: 聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,儘可能保證只抓取與需求相關的網頁信息。
而咱們從此要學習的,就是聚焦爬蟲。
HTTP和HTTPS
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議):是一種發佈和接收 HTML頁面的方法。
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下加入SSL層。
SSL(Secure Sockets Layer 安全套接層)主要用於Web的安全傳輸協議,在傳輸層對網絡鏈接進行加密,保障在Internet上數據傳輸的安全。
HTTP的端口號爲80,
HTTPS的端口號爲443
HTTP工做原理
網絡爬蟲抓取過程能夠理解爲模擬瀏覽器操做的過程。
瀏覽器的主要功能是向服務器發出請求,在瀏覽器窗口中展現您選擇的網絡資源,HTTP是一套計算機經過網絡進行通訊的規則。
HTTP的請求與響應
HTTP通訊由兩部分組成: 客戶端請求消息 與 服務器響應消息
瀏覽器發送HTTP請求的過程:
當用戶在瀏覽器的地址欄中輸入一個URL並按回車鍵以後,瀏覽器會向HTTP服務器發送HTTP請求。HTTP請求主要分爲「Get」和「Post」兩種方法。
當咱們在瀏覽器輸入URL http://www.baidu.com 的時候,瀏覽器發送一個Request請求去獲取 http://www.baidu.com 的html文件,服務器把Response文件對象發送回給瀏覽器。
瀏覽器分析Response中的 HTML,發現其中引用了不少其餘文件,好比Images文件,CSS文件,JS文件。 瀏覽器會自動再次發送Request去獲取圖片,CSS文件,或者JS文件。
當全部的文件都下載成功後,網頁會根據HTML語法結構,完整的顯示出來了。
URL(Uniform / Universal Resource Locator的縮寫):統一資源定位符,是用於完整地描述Internet上網頁和其餘資源的地址的一種標識方法。
基本格式:scheme://host[:port#]/path/…/?query-string
scheme:協議(例如:http, https, ftp)
host:服務器的IP地址或者域名
port#:服務器的端口(若是是走協議默認端口,缺省端口80)
path:訪問資源的路徑
query-string:參數,發送給http服務器的數據
anchor:錨(跳轉到網頁的指定錨點位置)
例如:
ftp://192.168.0.116:8080/index
http://item.jd.com/11936238.h...
客戶端HTTP請求
URL只是標識資源的位置,而HTTP是用來提交和獲取資源。客戶端發送一個HTTP請求到服務器的請求消息,包括如下格式:
請求行、請求頭部、空行、請求數據
四個部分組成,下圖給出了請求報文的通常格式。
一個典型的HTTP請求示例
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; MCITY=-343%3A340%3A; BDUSS=nF0MVFiMTVLcUh-Q2MxQ0M3STZGQUZ4N2hBa1FFRkIzUDI3QlBCZjg5cFdOd1pZQVFBQUFBJCQAAAAAAAAAAAEAAADpLvgG0KGyvLrcyfrG-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFaq3ldWqt5XN; H_PS_PSSID=1447_18240_21105_21386_21454_21409_21554; BD_UPN=12314753; sug=3; sugstore=0; ORIGIN=0; bdime=0; H_PS_645EC=7e2ad3QHl181NSPbFbd7PRUCE1LlufzxrcFmwYin0E6b%2BW8bbTMKHZbDP0g; BDSVRTM=0
請求方法
GET https://www.baidu.com/ HTTP/1.1
根據HTTP標準,HTTP請求可使用多種請求方法。
HTTP 0.9:只有基本的文本 GET 功能。
HTTP 1.0:完善的請求/響應模型,並將協議補充完整,定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP 1.1:在 1.0 基礎上進行更新,新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
HTTP 2.0(未普及):請求/響應首部的定義基本沒有改變,只是全部首部鍵必須所有小寫,並且請求行要獨立爲 :method、:scheme、:host、:path這些鍵值對。
序號 方法 描述
1 GET 請求指定的頁面信息,並返回實體主體。
2 HEAD 相似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件),數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。
4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5 DELETE 請求服務器刪除指定的頁面。
6 CONNECT HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。
7 OPTIONS 容許客戶端查看服務器的性能。
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。
HTTP請求主要分爲Get和Post兩種方法
GET是從服務器上獲取數據,POST是向服務器傳送數據
GET請求參數顯示,都顯示在瀏覽器網址上,HTTP服務器根據該請求所包含URL中的參數來產生響應內容,即「Get」請求的參數是URL的一部分。 例如: http://www.baidu.com/s?wd=Chi...
POST請求參數在請求體當中,消息長度沒有限制並且以隱式的方式進行發送,一般用來向HTTP服務器提交量比較大的數據(好比請求中包含許多參數或者文件上傳操做等),請求的參數包含在「Content-Type」消息頭裏,指明該消息體的媒體類型和編碼,
注意:避免使用Get方式提交表單,由於有可能會致使安全問題。 好比說在登錄表單中用Get方式,用戶輸入的用戶名和密碼將在地址欄中暴露無遺。
經常使用的請求報頭
Host:對應網址URL中的Web名稱和端口號,用於指定被請求資源的Internet主機和端口號,一般屬於URL的一部分。
Connection:表示客戶端與服務鏈接類型
Client 發起一個包含 Connection:keep-alive 的請求,HTTP/1.1使用 keep-alive 爲默認值。
Server收到請求後:
若是 Server 支持 keep-alive,回覆一個包含 Connection:keep-alive 的響應,不關閉鏈接;
若是 Server 不支持 keep-alive,回覆一個包含 Connection:close 的響應,關閉鏈接。
若是client收到包含 Connection:keep-alive 的響應,向同一個鏈接發送下一個請求,直到一方主動關閉鏈接。
keep-alive在不少狀況下可以重用鏈接,減小資源消耗,縮短響應時間,好比當瀏覽器須要多個文件時(好比一個HTML文件和相關的圖形文件),不須要每次都去請求創建鏈接。
Upgrade-Insecure-Requests:升級不安全的請求,意思是會在加載 http 資源時自動替換成 https 請求,讓瀏覽器再也不顯示https頁面中的http請求警報。
HTTPS 是以安全爲目標的 HTTP 通道,因此在 HTTPS 承載的頁面上不容許出現 HTTP 請求,一旦出現就是提示或報錯。
User-Agent:是客戶瀏覽器的名稱,之後會詳細講。
Accept:指瀏覽器或其餘客戶端能夠接受的MIME(Multipurpose Internet Mail Extensions(多用途互聯網郵件擴展))文件類型,服務器能夠根據它判斷並返回適當的文件格式。
舉例:
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是權重係數,範圍 0 =< q <= 1,q 值越大,請求越傾向於得到其「;」以前的類型表示的內容。若沒有指定q值,則默認爲1,按從左到右排序順序;若被賦值爲0,則用於表示瀏覽器不接受此內容類型。
Text:用於標準化地表示的文本信息,文本消息能夠是多種字符集和或者多種格式的;Application:用於傳輸應用程序數據或者二進制數據。詳細請點擊
Referer:代表產生請求的網頁來自於哪一個URL,用戶是從該 Referer頁面訪問到當前請求的頁面。這個屬性能夠用來跟蹤Web請求來自哪一個頁面,是從什麼網站來的等。
有時候遇到下載某網站圖片,須要對應的referer,不然沒法下載圖片,那是由於人家作了防盜鏈,原理就是根據referer去判斷是不是本網站的地址,若是不是,則拒絕,若是是,就能夠下載;
Accept-Encoding:指出瀏覽器能夠接受的編碼方式。編碼方式不一樣於文件格式,它是爲了壓縮文件並加速文件傳遞速度。瀏覽器在接收到Web響應以後先解碼,而後再檢查文件格式,許多情形下這能夠減小大量的下載時間。
舉例:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0
若是有多個Encoding同時匹配, 按照q值順序排列,本例中按順序支持 gzip, identity壓縮編碼,支持gzip的瀏覽器會返回通過gzip編碼的HTML頁面。 若是請求消息中沒有設置這個域服務器假定客戶端對各類內容編碼均可以接受。
Accept-Langeuage:指出瀏覽器能夠接受的語言種類,如en或en-us指英語,zh或者zh-cn指中文,當服務器可以提供一種以上的語言版本時要用到。
Accept-Charset:指出瀏覽器能夠接受的字符編碼。
舉例:Accept-Charset:iso-8859-1,gb2312,utf-8
ISO8859-1:一般叫作Latin-1。Latin-1包括了書寫全部西方歐洲語言不可缺乏的附加字符,英文瀏覽器的默認值是ISO-8859-1.
gb2312:標準簡體中文字符集;
utf-8:UNICODE 的一種變長字符編碼,能夠解決多種語言文本顯示問題,從而實現應用國際化和本地化。
若是在請求消息中沒有設置這個域,缺省是任何字符集均可以接受。
Cookie:瀏覽器用這個屬性向服務器發送Cookie。Cookie是在瀏覽器中寄存的小型數據體,它能夠記載和服務器相關的用戶信息,也能夠用來實現會話功能,之後會詳細講。
Content-Type:POST請求裏用來表示的內容類型。
舉例:Content-Type = Text/XML; charset=gb2312:
指明該請求的消息體中包含的是純文本的XML類型的數據,字符編碼採用「gb2312」。
服務端HTTP響應
HTTP響應也由四個部分組成,分別是: 狀態行、消息報頭、空行、響應正文
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" ....
經常使用的響應報頭(瞭解)
理論上全部的響應頭信息都應該是迴應請求頭的。可是服務端爲了效率,安全,還有其餘方面的考慮,會添加相對應的響應頭信息,從上圖能夠看到:
這個值告訴客戶端,服務端不但願客戶端緩存資源,在下次請求資源時,必需要重新請求服務器,不能從緩存副本中獲取資源。
Cache-Control是響應頭中很重要的信息,當客戶端請求頭中包含Cache-Control:max-age=0請求,明確表示不會緩存服務器資源時,Cache-Control做爲做爲迴應信息,一般會返回no-cache,意思就是說,"那就不緩存唄"。
當客戶端在請求頭中沒有包含Cache-Control時,服務端每每會定,不一樣的資源不一樣的緩存策略,好比說oschina在緩存圖片資源的策略就是Cache-Control:max-age=86400,這個意思是,從當前時間開始,在86400秒的時間內,客戶端能夠直接從緩存副本中讀取資源,而不須要向服務器請求。
這個字段做爲迴應客戶端的Connection:keep-alive,告訴客戶端服務器的tcp鏈接也是一個長鏈接,客戶端能夠繼續使用這個tcp鏈接發送http請求。
告訴客戶端,服務端發送的資源是採用gzip編碼的,客戶端看到這個信息後,應該採用gzip對資源進行解碼。
告訴客戶端,資源文件的類型,還有字符編碼,客戶端經過utf-8對資源進行解碼,而後對資源進行html解析。一般咱們會看到有些網站是亂碼的,每每就是服務器端沒有返回正確的編碼。
這個是服務端發送資源時的服務器時間,GMT是格林尼治所在地的標準時間。http協議中發送的時間都是GMT的,這主要是解決在互聯網上,不一樣時區在相互請求資源的時候,時間混亂問題。
這個響應頭也是跟緩存有關的,告訴客戶端在這個時間前,能夠直接訪問緩存副本,很顯然這個值會存在問題,由於客戶端和服務器的時間不必定會都是相同的,若是時間不一樣就會致使問題。因此這個響應頭是沒有Cache-Control:max-age=*這個響應頭準確的,由於max-age=date中的date是個相對時間,不只更好理解,也更準確。
這個含義與Cache-Control等同。
8.Server:Tengine/1.4.6
這個是服務器和相對應的版本,只是告訴客戶端服務器的信息。
這個響應頭告訴客戶端,服務器發送的資源的方式是分塊發送的。通常分塊發送的資源都是服務器動態生成的,在發送時還不知道發送資源的大小,因此採用分塊發送,每一塊都是獨立的,獨立的塊都能標示本身的長度,最後一塊是0長度的,當客戶端讀到這個0長度的塊時,就能夠肯定資源已經傳輸完了。
告訴緩存服務器,緩存壓縮文件和非壓縮文件兩個版本,如今這個字段用處並不大,由於如今的瀏覽器都是支持壓縮的。
響應狀態碼
響應狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
常見狀態碼:
100~199:表示服務器成功接收部分請求,要求客戶端繼續提交其他請求才能完成整個處理過程。
200~299:表示服務器成功接收請求並已完成整個處理過程。經常使用200(OK 請求成功)。
300~399:爲完成請求,客戶需進一步細化請求。例如:請求的資源已經移動一個新地址、經常使用302(所請求的頁面已經臨時轉移至新的url)、307和304(使用緩存資源)。
400~499:客戶端的請求有錯誤,經常使用404(服務器沒法找到被請求的頁面)、403(服務器拒絕訪問,權限不夠)。
500~599:服務器端出現錯誤,經常使用500(請求未完成。服務器遇到不可預知的狀況)。
Cookie 和 Session:
服務器和客戶端的交互僅限於請求/響應過程,結束以後便斷開,在下一次請求時,服務器會認爲新的客戶端。
爲了維護他們之間的連接,讓服務器知道這是前一個用戶發送的請求,必須在一個地方保存客戶端的信息。
Cookie:經過在 客戶端 記錄的信息肯定用戶的身份。
Session:經過在 服務器端 記錄的信息肯定用戶的身份。
Fiddler界面
設置好後,本機HTTP通訊都會通過127.0.0.1:8888代理,也就會被Fiddler攔截到。
請求 (Request) 部分詳解
Headers —— 顯示客戶端發送到服務器的 HTTP 請求的 header,顯示爲一個分級視圖,包含了 Web 客戶端信息、Cookie、傳輸狀態等。
Textview —— 顯示 POST 請求的 body 部分爲文本。
WebForms —— 顯示請求的 GET 參數 和 POST body 內容。
HexView —— 用十六進制數據顯示請求。
Auth —— 顯示響應 header 中的 Proxy-Authorization(代理身份驗證) 和 Authorization(受權) 信息.
Raw —— 將整個請求顯示爲純文本。
JSON - 顯示JSON格式文件。
XML —— 若是請求的 body 是 XML 格式,就是用分級的 XML 樹來顯示它。
響應 (Response) 部分詳解
Transformer —— 顯示響應的編碼信息。
Headers —— 用分級視圖顯示響應的 header。
TextView —— 使用文本顯示相應的 body。
ImageVies —— 若是請求是圖片資源,顯示響應的圖片。
HexView —— 用十六進制數據顯示響應。
WebView —— 響應在 Web 瀏覽器中的預覽效果。
Auth —— 顯示響應 header 中的 Proxy-Authorization(代理身份驗證) 和 Authorization(受權) 信息。
Caching —— 顯示此請求的緩存信息。
Privacy —— 顯示此請求的私密 (P3P) 信息。
Raw —— 將整個響應顯示爲純文本。
JSON - 顯示JSON格式文件。
XML —— 若是響應的 body 是 XML 格式,就是用分級的 XML 樹來顯示它 。
HTTP/HTTPS的GET和POST方法
urllib.parse.urlencode()
In [1]: import urllib.parse In [2]: word = {"wd" : "傳智播客"}
In [3]: urllib..parse.urlencode(word) Out[3]: "wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2"
In [4]: print (urllib.parse.unquote("wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2")) wd=傳智播客
通常HTTP請求提交數據,須要編碼成 URL編碼格式,而後作爲url的一部分,或者做爲參數傳到Request對象中。
Get方式
GET請求通常用於咱們向服務器獲取數據,好比說,咱們用百度搜索傳智播客:https://www.baidu.com/s?wd=傳...
瀏覽器的url會跳轉成如圖所示:
https://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
在其中咱們能夠看到在請求部分裏,http://www.baidu.com/s? 以後出現一個長長的字符串,其中就包含咱們要查詢的關鍵詞傳智播客,因而咱們能夠嘗試用默認的Get方式來發送請求。
import urllib.parse #負責url編碼處理 import urllib.request url = "http://www.baidu.com/s" word = {"wd":"傳智播客"} word = urllib.parse.urlencode(word) #轉換成url編碼格式(字符串) newurl = url + "?" + word # url首個分隔符就是 ? 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())
批量爬取貼吧頁面數據
首先咱們建立一個python文件, tiebaSpider.py,咱們要完成的是,輸入一個百度貼吧的地址,好比:
百度貼吧LOL吧第一頁:http://tieba.baidu.com/f?kw=l...
第二頁: http://tieba.baidu.com/f?kw=l...
第三頁: http://tieba.baidu.com/f?kw=l...
發現規律了吧,貼吧中每一個頁面不一樣之處,就是url最後的pn的值,其他的都是同樣的,咱們能夠抓住這個規律。
複製代碼
#!/usr/bin/env python # -*- coding:utf-8 -*- import urllib.request import urllib.parse def loadPage(url, filename): """ 做用:根據url發送請求,獲取服務器響應文件 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內容寫入到本地 html:服務器相應文件內容 """ print ("正在保存 " + filename) # 文件寫入 with open(filename, "wb+") as f: f.write(html) print ("-" * 30) def tiebaSpider(url, beginPage, endPage): """ 做用:貼吧爬蟲調度器,負責組合處理每一個頁面的url url : 貼吧url的前部分 beginPage : 起始頁 endPage : 結束頁 """ 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("請輸入須要爬取的貼吧名:") beginPage = int(input("請輸入起始頁:")) endPage = int(input("請輸入結束頁:")) url = "http://tieba.baidu.com/f?" key = urllib.parse.urlencode({"kw": kw}) fullurl = url + key tiebaSpider(fullurl, beginPage, endPage) 複製代碼
其實不少網站都是這樣的,同類網站下的html頁面編號,分別對應網址後的網頁序號,只要發現規律就能夠批量爬取頁面了。
POST方式:
上面咱們說了Request請求對象的裏有data參數,它就是用在POST裏的,咱們要傳送的數據就是這個參數data,data是一個字典,裏面要匹配鍵值對。
有道詞典翻譯網站:
輸入測試數據,再經過使用Fiddler觀察,其中有一條是POST請求,而向服務器發送的請求數據並非在url裏,那麼咱們能夠試着模擬這個POST請求。
因而,咱們能夠嘗試用POST方式發送請求。
複製代碼 #!/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", } # 用戶接口輸入 # 發送到web服務器的表單數據 formdata = { "type" : "AUTO", "i" : "我愛你", "doctype" : "json", "xmlVersion" : "1.6", "keyfrom" : "fanyi.web", "ue" : "UTF-8", "typoResult" : "true" } # 通過urlencode轉碼 data = urllib.parse.urlencode(formdata).encode('utf-8') # 若是Request()方法裏的data參數有值,那麼這個請求就是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()) 複製代碼
發送POST請求時,須要特別注意headers的一些屬性:
Content-Length: 144: 是指發送的表單數據長度爲144,也就是字符個數是144個。
X-Requested-With: XMLHttpRequest :表示Ajax異步請求。
Content-Type: application/x-www-form-urlencoded : 表示瀏覽器提交 Web 表單時使用,表單數據會按照 name1=value1&name2=value2 鍵值對形式進行編碼。
獲取AJAX加載的內容
有些網頁內容使用AJAX加載,只要記得,AJAX通常返回的是JSON,直接對AJAX地址進行post或get,就返回JSON數據了。
"做爲一名爬蟲工程師,你最須要關注的,是數據的來源"
import urllib import urllib2
url = "https://movie.douban.com/j/chart/top_list?type=11&interval_id=100%3A90&action" headers={"User-Agent": "Mozilla...."}
formdata = { 'start':'0', 'limit':'10' } data = urllib.urlencode(formdata) request = urllib2.Request(url, data = data, headers = headers) response = urllib2.urlopen(request) print response.read()
url = "https://movie.douban.com/j/chart/top_list?" headers={"User-Agent": "Mozilla...."}
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()
問題:爲何有時候POST也能在URL內看到數據?
GET方式是直接以連接形式訪問,連接中包含了全部的參數,服務器端用Request.QueryString獲取變量的值。若是包含了密碼的話是一種不安全的選擇,不過你能夠直觀地看到本身提交了什麼內容。
POST則不會在網址上顯示全部的參數,服務器端用Request.Form獲取提交的數據,在Form提交的時候。可是HTML代碼裏若是不指定 method 屬性,則默認爲GET請求,Form中提交的數據將會附加在url以後,以?分開與url分開。
表單數據能夠做爲 URL 字段(method="get")或者 HTTP POST (method="post")的方式來發送。好比在下面的HTML代碼中,表單數據將由於 (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模擬登錄
View Code
處理HTTPS請求 SSL證書驗證
如今隨處可見 https 開頭的網站,urllib2能夠爲 HTTPS 請求驗證SSL證書,就像web瀏覽器同樣,若是網站的SSL證書是通過CA認證的,則可以正常訪問,如:https://www.baidu.com/等...
若是SSL證書驗證不經過,或者操做系統不信任服務器的安全證書,好比瀏覽器在訪問12306網站如:https://www.12306.cn/mormhweb...,會警告用戶證書不受信任。(聽說 12306 網站證書是本身作的,沒有經過CA認證)
View Code
關於CA
CA(Certificate Authority)是數字證書認證中心的簡稱,是指發放、管理、廢除數字證書的受信任的第三方機構,如北京數字認證股份有限公司、上海市數字證書認證中心有限公司等...
CA的做用是檢查證書持有者身份的合法性,並簽發證書,以防證書被僞造或篡改,以及對證書和密鑰進行管理。
現實生活中能夠用身份證來證實身份, 那麼在網絡世界裏,數字證書就是身份證。和現實生活不一樣的是,並非每一個上網的用戶都有數字證書的,每每只有當一我的須要證實本身的身份的時候才須要用到數字證書。
普通用戶通常是不須要,由於網站並不關心是誰訪問了網站,如今的網站只關心流量。可是反過來,網站就須要證實本身的身份了。
好比說如今釣魚網站不少的,好比你想訪問的是www.baidu.com,但其實你訪問的是www.daibu.com」,因此在提交本身的隱私信息以前須要驗證一下網站的身份,要求網站出示數字證書。
通常正常的網站都會主動出示本身的數字證書,來確保客戶端和網站服務器之間的通訊數據是加密安全的。