什麼是爬蟲?html
爬蟲:就是抓取網頁數據的程序。python
HTTP和HTTPSweb
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議):是一種發佈和接收 HTML頁面的方法。chrome
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)簡單講是HTTP的安全版,在HTTP下加入SSL層。json
SSL(Secure Sockets Layer 安全套接層)主要用於Web的安全傳輸協議,在傳輸層對網絡鏈接進行加密,保障在Internet上數據傳輸的安全。瀏覽器
瀏覽器發送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文件。cookie
當全部的文件都下載成功後,網頁會根據HTML語法結構,完整的顯示出來了。
URL(Uniform / Universal Resource Locator的縮寫)
定義:統一資源定位符,是用於完整地描述Internet上網頁和其餘資源的地址的一種標識方法。
基本格式:scheme://host[:port#]/path/…/[?query-string][#anchor]
客戶端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 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh,zh-CN;q=0.8,ar;q=0.6,zh-TW;q=0.4 Cookie: BAIDUID=AE4D1DA6B2D6689BB8C557B3436893E3:FG=1; BIDUPSID=AE4D1DA6B2D6689BB8C557B3436893E3; PSTM=1501466227; BD_UPN=12314353; BD_CK_SAM=1; PSINO=1; H_PS_PSSID=1420_25548_21080_20929; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDSVRTM=0
1. Host (主機和端口號) Host:對應網址URL中的Web名稱和端口號,用於指定被請求資源的Internet主機和端口號,一般屬於URL的一部分。 2. Connection (連接類型) 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文件和相關的圖形文件),不須要每次都去請求創建鏈接。 3. Upgrade-Insecure-Requests (升級爲HTTPS請求) Upgrade-Insecure-Requests:升級不安全的請求,意思是會在加載 http 資源時自動替換成 https 請求,讓瀏覽器再也不顯示https頁面中的http請求警報。 HTTPS 是以安全爲目標的 HTTP 通道,因此在 HTTPS 承載的頁面上不容許出現 HTTP 請求,一旦出現就是提示或報錯。 4. User-Agent (瀏覽器名稱) User-Agent:是客戶瀏覽器的名稱,之後會詳細講。 5. Accept (傳輸文件類型) 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:用於傳輸應用程序數據或者二進制數據。詳細請點擊 6. Referer (頁面跳轉處) Referer:代表產生請求的網頁來自於哪一個URL,用戶是從該 Referer頁面訪問到當前請求的頁面。這個屬性能夠用來跟蹤Web請求來自哪一個頁面,是從什麼網站來的等。 有時候遇到下載某網站圖片,須要對應的referer,不然沒法下載圖片,那是由於人家作了防盜鏈,原理就是根據referer去判斷是不是本網站的地址,若是不是,則拒絕,若是是,就能夠下載; 7. Accept-Encoding(文件編解碼格式) Accept-Encoding:指出瀏覽器能夠接受的編碼方式。編碼方式不一樣於文件格式,它是爲了壓縮文件並加速文件傳遞速度。瀏覽器在接收到Web響應以後先解碼,而後再檢查文件格式,許多情形下這能夠減小大量的下載時間。 舉例:Accept-Encoding:gzip;q=1.0, identity; q=0.5, *;q=0 若是有多個Encoding同時匹配, 按照q值順序排列,本例中按順序支持 gzip, identity壓縮編碼,支持gzip的瀏覽器會返回通過gzip編碼的HTML頁面。 若是請求消息中沒有設置這個域服務器假定客戶端對各類內容編碼均可以接受。 8. Accept-Language(語言種類) Accept-Langeuage:指出瀏覽器能夠接受的語言種類,如en或en-us指英語,zh或者zh-cn指中文,當服務器可以提供一種以上的語言版本時要用到。 9. Accept-Charset(字符編碼) Accept-Charset:指出瀏覽器能夠接受的字符編碼。 舉例:Accept-Charset:iso-8859-1,gb2312,utf-8 ISO8859-1:一般叫作Latin-1。Latin-1包括了書寫全部西方歐洲語言不可缺乏的附加字符,英文瀏覽器的默認值是ISO-8859-1. gb2312:標準簡體中文字符集; utf-8:UNICODE 的一種變長字符編碼,能夠解決多種語言文本顯示問題,從而實現應用國際化和本地化。 若是在請求消息中沒有設置這個域,缺省是任何字符集均可以接受。 10. Cookie (Cookie) Cookie:瀏覽器用這個屬性向服務器發送Cookie。Cookie是在瀏覽器中寄存的小型數據體,它能夠記載和服務器相關的用戶信息,也能夠用來實現會話功能,之後會詳細講。 11. Content-Type (POST數據類型) Content-Type:POST請求裏用來表示的內容類型。 舉例:Content-Type = Text/XML; charset=gb2312: 指明該請求的消息體中包含的是純文本的XML類型的數據,字符編碼採用「gb2312」。
服務器和客戶端的交互僅限於請求/響應過程,結束以後便斷開,在下一次請求時,服務器會認爲新的客戶端。
爲了維護他們之間的連接,讓服務器知道這是前一個用戶發送的請求,必須在一個地方保存客戶端的信息。
Cookie:經過在 客戶端 記錄的信息肯定用戶的身份。
Session:經過在 服務器端 記錄的信息肯定用戶的身份。
HTTP請求方法
序號 方法 描述 1 GET 請求指定的頁面信息,並返回實體主體。 2 HEAD 相似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件),數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。 4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。 5 DELETE 請求服務器刪除指定的頁面。 6 CONNECT HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。 7 OPTIONS 容許客戶端查看服務器的性能。 8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。
主要方法get和post請求
GET是從服務器上獲取數據,POST是向服務器傳送數據
GET請求參數顯示,都顯示在瀏覽器網址上,HTTP服務器根據該請求所包含URL中的參數來產生響應內容,即「Get」請求的參數是URL的一部分。 例如: http://www.baidu.com/s?wd=Chinese
POST請求參數在請求體當中,消息長度沒有限制並且以隱式的方式進行發送,一般用來向HTTP服務器提交量比較大的數據(好比請求中包含許多參數或者文件上傳操做等),請求的參數包含在「Content-Type」消息頭裏,指明該消息體的媒體類型和編碼.
HTTP響應狀態碼
1xx:信息 100 Continue 服務器僅接收到部分請求,可是一旦服務器並無拒絕該請求,客戶端應該繼續發送其他的請求。 101 Switching Protocols 服務器轉換協議:服務器將聽從客戶的請求轉換到另一種協議。 2xx:成功 200 OK 請求成功(其後是對GET和POST請求的應答文檔) 201 Created 請求被建立完成,同時新的資源被建立。 202 Accepted 供處理的請求已被接受,可是處理未完成。 203 Non-authoritative Information 文檔已經正常地返回,但一些應答頭可能不正確,由於使用的是文檔的拷貝。 204 No Content 沒有新文檔。瀏覽器應該繼續顯示原來的文檔。若是用戶按期地刷新頁面,而Servlet能夠肯定用戶文檔足夠新,這個狀態代碼是頗有用的。 205 Reset Content 沒有新文檔。但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容。 206 Partial Content 客戶發送了一個帶有Range頭的GET請求,服務器完成了它。 3xx:重定向 300 Multiple Choices 多重選擇。連接列表。用戶能夠選擇某連接到達目的地。最多容許五個地址。 301 Moved Permanently 所請求的頁面已經轉移至新的url。 302 Moved Temporarily 所請求的頁面已經臨時轉移至新的url。 303 See Other 所請求的頁面可在別的url下被找到。 304 Not Modified 未按預期修改文檔。客戶端有緩衝的文檔併發出了一個條件性的請求(通常是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩衝的文檔還能夠繼續使用。 305 Use Proxy 客戶請求的文檔應該經過Location頭所指明的代理服務器提取。 306 Unused 此代碼被用於前一版本。目前已再也不使用,可是代碼依然被保留。 307 Temporary Redirect 被請求的頁面已經臨時移至新的url。 4xx:客戶端錯誤 400 Bad Request 服務器未能理解請求。 401 Unauthorized 被請求的頁面須要用戶名和密碼。 401.1 登陸失敗。 401.2 服務器配置致使登陸失敗。 401.3 因爲 ACL 對資源的限制而未得到受權。 401.4 篩選器受權失敗。 401.5 ISAPI/CGI 應用程序受權失敗。 401.7 訪問被 Web 服務器上的 URL 受權策略拒絕。這個錯誤代碼爲 IIS 6.0 所專用。 402 Payment Required 此代碼尚沒法使用。 403 Forbidden 對被請求頁面的訪問被禁止。 403.1 執行訪問被禁止。 403.2 讀訪問被禁止。 403.3 寫訪問被禁止。 403.4 要求 SSL。 403.5 要求 SSL 128。 403.6 IP 地址被拒絕。 403.7 要求客戶端證書。 403.8 站點訪問被拒絕。 403.9 用戶數過多。 403.10 配置無效。 403.11 密碼更改。 403.12 拒絕訪問映射表。 403.13 客戶端證書被吊銷。 403.14 拒絕目錄列表。 403.15 超出客戶端訪問許可。 403.16 客戶端證書不受信任或無效。 403.17 客戶端證書已過時或還沒有生效。 403.18 在當前的應用程序池中不能執行所請求的 URL。這個錯誤代碼爲 IIS 6.0 所專用。 403.19 不能爲這個應用程序池中的客戶端執行 CGI。這個錯誤代碼爲 IIS 6.0 所專用。 403.20 Passport 登陸失敗。這個錯誤代碼爲 IIS 6.0 所專用。 404 Not Found 服務器沒法找到被請求的頁面。 404.0 沒有找到文件或目錄。 404.1 沒法在所請求的端口上訪問 Web 站點。 404.2 Web 服務擴展鎖定策略阻止本請求。 404.3 MIME 映射策略阻止本請求。 405 Method Not Allowed 請求中指定的方法不被容許。 406 Not Acceptable 服務器生成的響應沒法被客戶端所接受。 407 Proxy Authentication Required 用戶必須首先使用代理服務器進行驗證,這樣請求才會被處理。 408 Request Timeout 請求超出了服務器的等待時間。 409 Conflict 因爲衝突,請求沒法被完成。 410 Gone 被請求的頁面不可用。 411 Length Required "Content-Length" 未被定義。若是無此內容,服務器不會接受請求。 412 Precondition Failed 請求中的前提條件被服務器評估爲失敗。 413 Request Entity Too Large 因爲所請求的實體的太大,服務器不會接受請求。 414 Request-url Too Long 因爲url太長,服務器不會接受請求。當post請求被轉換爲帶有很長的查詢信息的get請求時,就會發生這種狀況。 415 Unsupported Media Type 因爲媒介類型不被支持,服務器不會接受請求。 416 Requested Range Not Satisfiable 服務器不能知足客戶在請求中指定的Range頭。 417 Expectation Failed 執行失敗。 423 鎖定的錯誤。 5xx:服務器錯誤 500 Internal Server Error 請求未完成。服務器遇到不可預知的狀況。 500.12 應用程序正忙於在 Web 服務器上從新啓動。 500.13 Web 服務器太忙。 500.15 不容許直接請求 Global.asa。 500.16 UNC 受權憑據不正確。這個錯誤代碼爲 IIS 6.0 所專用。 500.18 URL 受權存儲不能打開。這個錯誤代碼爲 IIS 6.0 所專用。 500.100 內部 ASP 錯誤。 501 Not Implemented 請求未完成。服務器不支持所請求的功能。 502 Bad Gateway 請求未完成。服務器從上游服務器收到一個無效的響應。 502.1 CGI 應用程序超時。 · 502.2 CGI 應用程序出錯。 503 Service Unavailable 請求未完成。服務器臨時過載或當機。 504 Gateway Timeout 網關超時。 505 HTTP Version Not Supported 服務器不支持請求中指明的HTTP協議版本
瀏覽器內核
瀏覽器 內核
IE Trident
Chrome Webkit
Firefox Gecho
Opera Pesto
Safari(Apple) Webkit
HTTP代理工具Fiddler
Fiddler是一款強大Web調試工具,它能記錄全部客戶端和服務器的HTTP請求.
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 樹來顯示它。
Responser部分詳解
- Transformer —— 顯示響應的編碼信息。
- Headers —— 用分級視圖顯示響應的 header。
- TextView —— 使用文本顯示相應的 body。
- ImageVies —— 若是請求是圖片資源,顯示響應的圖片。
- HexView —— 用十六進制數據顯示響應。
- WebView —— 響應在 Web 瀏覽器中的預覽效果。
- Auth —— 顯示響應 header 中的 Proxy-Authorization(代理身份驗證) 和 Authorization(受權) 信息。
- Caching —— 顯示此請求的緩存信息。
- Privacy —— 顯示此請求的私密 (P3P) 信息。
- Raw —— 將整個響應顯示爲純文本。
- JSON - 顯示JSON格式文件。
- XML —— 若是響應的 body 是 XML 格式,就是用分級的 XML 樹來顯示它 。
瞭解了這些知識後,接下來真正邁向爬蟲之路.......
所謂網頁抓取,就是把URL地址中指定的網絡資源從網絡流中讀取出來,保存到本地。 在Python中有不少庫能夠用來抓取網頁,先學習urllib2
。
urllib2模塊直接導入就能夠用,在python3中urllib2被改成urllib.request
開始爬蟲須要準備的一些工具
(1)下載Fiddeler抓包工具,百度直接下載安裝就能夠(抓包)
(2)下載chrome瀏覽器代理插件 Proxy-SwitchyOmega(代理)
(3)下載chrome瀏覽器插件XPath(解析HTML)
(4)工具網站:
http://www.json.cn/ (json解析網站)
http://tool.chinaz.com/tools/urlencode.aspx (url編碼解碼網站)
先寫個簡單的爬蟲百度頁面
urlopen
# _*_ coding:utf-8 _*_ import urllib2 #向指定的url地址發送請求,並返回服務器響應的類文件對象 response = urllib2.urlopen('http://www.baidu.com/') #服務器返回的類文件對象支持python文件對象的操做方法 #read()方法就是讀取文件裏的所有內容,返回字符串 html = response.read() print html
urllib2默認的User-Agent是Python-urllib/2.7,容易被檢查到是爬蟲,因此咱們要構造一個請求對象,要用到request方法。
模擬瀏覽器訪問
瀏覽器訪問時經過抓包工具得到的headers信息以下:
GET https://www.baidu.com/ HTTP/1.1 Host: www.baidu.com Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh,zh-CN;q=0.8,ar;q=0.6,zh-TW;q=0.4 Cookie: BAIDUID=AE4D1DA6B2D6689BB8C557B3436893E3:FG=1; BIDUPSID=AE4D1DA6B2D6689BB8C557B3436893E3; PSTM=1501466227; BD_CK_SAM=1; PSINO=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BD_HOME=0; H_PS_PSSID=1420_25548_21080_20929; BD_UPN=12314353
咱們要設置User-Agent模仿瀏覽器去訪問數據
# _*_ coding:utf-8 _*_ import urllib2 # User-Agent是爬蟲與反爬蟲的第一步 ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'} # 經過urllib2.Request()方法構造一個請求對象 request = urllib2.Request('http://www.baidu.com/',headers=ua_headers) #向指定的url地址發送請求,並返回服務器響應的類文件對象 response = urllib2.urlopen(request) # 服務器返回的類文件對象支持python文件對象的操做方法 # read()方法就是讀取文件裏的所有內容,返回字符串 html = response.read() print html
Request總共三個參數,除了必需要有url參數,還有下面兩個:
data(默認空):是伴隨 url 提交的數據(好比要post的數據),同時 HTTP 請求將從 "GET"方式 改成 "POST"方式。
headers(默認空):是一個字典,包含了須要發送的HTTP報頭的鍵值對。
response的經常使用方法
# _*_ coding:utf-8 _*_ import urllib2 # User-Agent是爬蟲與反爬蟲的第一步 ua_headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'} # 經過urllib2.Request()方法構造一個請求對象 request = urllib2.Request('http://www.baidu.com/',headers=ua_headers) #向指定的url地址發送請求,並返回服務器響應的類文件對象 response = urllib2.urlopen(request) # 服務器返回的類文件對象支持python文件對象的操做方法 # read()方法就是讀取文件裏的所有內容,返回字符串 html = response.read() # 返回HTTP的響應嗎,成功返回200,4服務器頁面出錯,5服務器問題 print response.getcode() #200 # 返回數據的實際url,防止重定向 print response.geturl() #https://www.baidu.com/ # 返回服務器響應的HTTP報頭 print response.info() # print html
隨機選擇一個Use-Agent
爲了防止封IP,先生成一個user-agent列表,而後從中隨機選擇一個
# _*_ coding:utf-8 _*_ import urllib2 import random url = 'http:/www.baidu.com/' # 能夠試User-Agent列表,也能夠是代理列表 ua_list = ["Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1", "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3", "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24" ] # 在User-Agent列表中隨機選擇一個User-Agent user_agent = random.choice(ua_list) # 構造一個請求 request = urllib2.Request(url) # add_header()方法添加/修改一個HTTP報頭 request.add_header('User-Agent',user_agent) #get_header()獲取一個已有的HTTP報頭的值,注意只能第一個字母大寫,後面的要小寫 print request.get_header('User-agent')
urllib和urllib2都是接受URL請求的相關模塊,可是提供了不一樣的功能,最顯著的區別以下:
(1)urllib僅能夠接受URL,不能建立,設置headers的request類實例;
(2)可是urllib提供urlencode()方法用來GET查詢字符串的產生,而urllib2則沒有(這是urllib和urllib2常常一塊兒使用的主要緣由)
(3)編碼工做使用urllib的urlencode()函數,幫咱們講key:value這樣的鍵值對轉換成‘key=value’這樣的字符串,解碼工做可使用urllib的unquote()
函數
urllib.encode()的使用
urlencode()裏面必須是字典類型
# _*_ coding:utf-8 _*_ import urllib dic = {'derek':'編碼'} print urllib.urlencode(dic) #derek=%E7%BC%96%E7%A0%81 m = urllib.urlencode(dic) print urllib.unquote(m) #derek=編碼
GET請求通常用於咱們向服務器獲取數據,好比說,咱們用百度搜索知乎
:https://www.baidu.com/s?wd=知乎
發現GEThttps://www.baidu.com/s?wd=%E7%9F%A5%E4%B9%8E,後面是一個長長的字符串,urldecode後發現就是知乎
用urllib.urlencode()進行轉碼,而後組合url
# _*_ coding:utf-8 _*_ import urllib,urllib2 url = 'http://www.baidu.com/s' headers = {'UserAgent':'Mozilla'} keyword = raw_input('請輸入關鍵字:') wd = urllib.urlencode({'wd':keyword}) fullurl = url + '?' + wd print fullurl request = urllib2.Request(fullurl,headers=headers) response = urllib2.urlopen(request) print response.read()
而後輸入關鍵字,爬取下對應的內容
先了解貼吧url組成:
每一個貼吧url都是以'https://tieba.baidu.com/f?'開頭,而後是關鍵字 kw=‘’貼吧名字‘’,再後面是 &pn=頁數 (pn=0第一頁,pn=50第二頁,依次類推)
1.先寫一個main,提示用戶輸入要爬取的貼吧名,並用urllib.urlencode()進行轉碼,而後組合url
2.接下來,寫一個百度貼吧爬蟲接口tiebaSpider(),須要傳遞3個參數給這個接口, 一個是main裏組合的url地址,以及起始頁碼和終止頁碼,表示要爬取頁碼的範圍。
3.前面寫出一個爬取一個網頁的代碼。而後,將它封裝成一個小函數loadPage(),供咱們使用。
4.將爬取到的每頁的信息存儲在本地磁盤上,咱們能夠簡單寫一個存儲文件的接口writePage()
# _*_ coding:utf-8 _*_ import urllib,urllib2 def loadPage(url,filename): #根據url發送請求,獲取服務器響應文件 print '正在下載' + filename headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'} request = urllib2.Request(url,headers = headers) content = urllib2.urlopen(request).read() return content def writePage(html,filename): #將html內容寫入到本地 print '正在保存' + filename with open(unicode(filename,'utf-8'),'w') as f: f.write(html) print '_' * 30 def tiebaSpider(url,beginPage,endPage): #貼吧爬蟲調度器,負責組合處理每一個頁面的url 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) writePage(html,filename) if __name__ == '__main__': kw = raw_input('請輸入貼吧名:') beginPage = int(raw_input('請輸入起始頁:')) endPage = int(raw_input('請輸入結束頁:')) url = 'https://tieba.baidu.com/f?' key = urllib.urlencode({'kw':kw}) fullurl = url + key tiebaSpider(fullurl,beginPage,endPage)
經過輸入想要搜索的貼吧名字,爬取內容並保存到本地
爬蟲最須要關注的不是頁面信息,而是頁面信息的數據來源
Ajax方式加載的頁面,數據來源必定是JSON,直接對AJAX地址進行post或get,拿到JSON,就是拿到了網頁數據,
(1)先經過瀏覽器訪問豆瓣電影排行榜
https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=
(2)瀏覽器訪問後,經過抓包工具就能夠獲取咱們想要的一些信息
只要response裏面有 JSON數據,咱們就能夠找到服務器的數據來源
分析發現變更的是start value和limit value, type,interval_id,action,固定不變,這三個url中已經包含了,因此formdata只用傳start和limit
import urllib import urllib2 url = 'https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=100:90&action=' headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'} # start和limit能夠本身隨便設置 formdata = {'start':'20','limit':'100'} data = urllib.urlencode(formdata) request = urllib2.Request(url,data = data,headers=headers) response = urllib2.urlopen(request) print response.read()