神級程序員從第一步教你如何成為一名優秀的爬蟲工程師!

沒有哪個人是一開始就是大牛,都是從零基礎開始開始過來的 所以零基礎的小夥伴也會成為大牛的一天,程序員不是一兩天就能到達那種高度的,是寫出來的,多思考多變化。代碼多敲就熟練了,不管天賦怎樣,勤能補拙嘛,大家可以加我python交流群:58937142,裡面新手資料,框架,爬蟲。web都有,都是可以免費獲取的,還有大牛解答各種難題,不失為是一個學習的好地方,小編在這裡邀請大家加入我的大家庭。歡迎你的到來。一起交流學習!共同進步!大家最好是收藏了在看呢!

爬蟲的基本流程

  • 發起請求

  • 通過HTTP庫向目標站點發起請求,也就是發送一個Request,請求可以包含額外的header等信息,等待服務器響應Response

  • 獲取響應內容

  • 如果服務器能正常響應,會得到一個Response,Response的內容便是所要獲取的頁面內容,類型可能是HTML,Json字符串,二進制數據(圖片或者視頻)等類型

  • 解析內容

  • 得到的內容可能是HTML,可以用正則表達式,頁面解析庫進行解析,可能是Json,可以直接轉換為Json對象解析,可能是二進制數據,可以做保存或者進一步的處理

  • 保存數據

  • 保存形式多樣,可以存為文本,也可以保存到數據庫,或者保存特定格式的文件

什麼是Request,Response

  • 瀏覽器發送消息給網址所在的服務器,這個過程就叫做HTPP Request

  • 服務器收到瀏覽器發送的消息後,能夠根據瀏覽器發送消息的內容,做相應的處理,然後把消息回傳給瀏覽器,這個過程就是HTTP Response

  • 瀏覽器收到服務器的Response信息後,會對信息進行相應的處理,然後展示

Request中包含什麼?

請求方式

主要有:GET/POST兩種類型常用,另外還有HEAD/PUT/DELETE/OPTIONS

  • GETPOST的區別就是:

  • GET是把參數數據隊列加到提交表單的ACTION屬性所指的URL中,值和表單內各個字段一一對應,在URL中可以看到。

  • POST是通過HTTP POST機制,將表單內各個字段放置在HTML HEADER內一起傳送到ACTION屬性所指的URL中(用戶看不到此過程)

  • GET:從服務器上獲取數據。使用GET方法應該只用在讀取數據,而不應當被用於產生“副作用”的操作中,例如在Web Application中。其中一個原因是GET可能會被網絡蜘蛛等隨意訪問。

  • POST:向指定資源提交數據,請求服務器進行處理(例如提交表單或者上傳文件)。

  • HEAD:與GET方法一樣,都是向服務器發出指定資源的請求。只不過服務器將不傳回資源的本文部分。它的好處在於,使用這個方法可以在不必傳輸全部內容的情況下,就可以獲取其中“關於該資源的信息”(元信息或稱元數據)。

  • PUT:向指定資源位置上傳其最新內容。

  • OPTIONS:這個方法可使服務器傳回該資源所支持的所有HTTP請求方法。用'*'來代替資源名稱,向Web服務器發送OPTIONS請求,可以測試服務器功能是否正常運作。

  • DELETE:請求服務器刪除Request-URI所標識的資源。

請求URL

URL,即統一資源定位符,也就是我們說的網址,統一資源定位符是對可以從互聯網上得到的資源的位置和訪問方法的一種簡潔的表示,是互聯網上標準資源的地址。互聯網上的每個文件都有一個唯一的URL,它包含的信息指出文件的位置以及瀏覽器應該怎麼處理它。

URL的格式由三個部分組成:

  • 協議(或稱為服務方式)。

  • 存有該資源的主機IP地址(有時也包括端口號)。

  • 主機資源的具體地址,如目錄和文件名等。

爬蟲爬取數據時必須要有一個目標的URL才可以獲取數據,因此,它是爬蟲獲取數據的基本依據。

請求頭

包含請求時的頭部信息,如User-Agent,Host,Cookies等信息

請求體

請求攜帶的數據,如提交表單數據時候的表單數據(POST)

Response中包含了什麼

所有HTTP響應的第一行都是狀態行,依次是當前HTTP版本號,3位數字組成的狀態代碼,以及描述狀態的短語,彼此由空格分隔。

響應狀態

有多種響應狀態,如:

200代表成功,301跳轉,404找不到頁面,502服務器錯誤 1xx消息——請求已被服務器接收,繼續處理 2xx成功——請求已成功被服務器接收、理解、並接受 3xx重定向——需要後續操作才能完成這一請求 4xx請求錯誤——請求含有詞法錯誤或者無法被執行 5xx服務器錯誤——服務器在處理某個正確請求時發生錯誤 常見代碼: 200 OK 請求成功 400 Bad Request 客戶端請求有語法錯誤,不能被服務器所理解 401 Unauthorized 請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用 403 Forbidden 服務器收到請求,但是拒絕提供服務 404 Not Found 請求資源不存在,eg:輸入了錯誤的URL 500 Internal Server Error 服務器發生不可預期的錯誤 503 Server Unavailable 服務器當前不能處理客戶端的請求,一段時間後可能恢復正常 301 目標永久性轉移 302 目標暫時性轉移

響應頭

如內容類型,類型的長度,服務器信息,設置Cookie

響應體

最主要的部分,包含請求資源的內容,如網頁HTMl,圖片,二進制數據等

能爬取什麼樣的數據

  • 網頁文本:如HTML文檔,Json格式化文本等

  • 圖片:獲取到的是二進制文件,保存為圖片格式

  • 視頻:同樣是二進制文件

  • 其他:只要請求到的,都可以獲取

如何解析數據

  • 直接處理

  • Json解析

  • 正則表達式處理

  • BeautifulSoup解析處理

  • PyQuery解析處理

  • XPath解析處理

import urllib

Urllib庫的簡介

Urllib是python內置的HTTP請求庫,包括以下模塊

  • urllib.request: 請求模塊

  • urllib.error: 異常處理模塊

  • urllib.parse: url解析模塊

  • urllib.response: 響應請求

  • Type: module

  • Docstring:

    Response classes used by urllib.

  • The base class, addbase, defines a minimal file-like interface,including read() and readline().

  • The typical response object is an addinfourl instance, which defines an info() method that returns

    headers and a geturl() method that returns the url.

urllib.request

urllib.request.urlopen

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

參數:

Open the URL url, which can be either a string or a Request object.(url可以是一個網址的字符串,或是一個Request對象)

data must be an object specifying additional data to be sent to the server, or None if no such data is needed. See Request for details.

```

返回一個file-like對象(可以像操作context一樣進行管理和擁有一些實例方法):

```

For HTTP and HTTPS URLs, this function returns a http.client.HTTPResponse

object slightly modified. In addition to the three new methods above, the

msg attribute contains the same information as the reason attribute ---

the reason phrase returned by the server --- instead of the response

headers as it is specified in the documentation for HTTPResponse.

For FTP, file, and data URLs and requests explicitly handled by legacy

URLopener and FancyURLopener classes, this function returns a

urllib.response.addinfourl object.

Note that None may be returned if no handler handles the request (though

the default installed global OpenerDirector uses UnknownHandler to ensure

this never happens).

In addition, if proxy settings are detected (for example, when a *_proxy

environment variable like http_proxy is set), ProxyHandler is default

installed and makes sure the requests are handled through the proxy.

常用實例方法

  • geturl() - return the URL of the resource retrieved, commonly used to

    determine if a redirect was followed

  • info() - return the meta-information of the page, such as headers, in the

    form of an email.message_from_string() instance (see Quick Reference to

    HTTP Headers)

  • getcode() - return the HTTP status code of the response. Raises URLError

    on errors.

示例:

import urllib.request
<html>
import urllib
<html>
對象名類型
requrllib.request.Request
responsehttp.client.HTTPResponse
response.read()bytes
response.info()http.client.HTTPMessage
the_pagestr
type(response.info())
http.client.HTTPMessage
print(response.geturl()) # 返回真實網址
https://www.baidu.com

urlopen一般常用的有三個參數,它的參數如下:urllib.requeset.urlopen(url,data,timeout)

  • data參數的使用

    上述的例子是通過請求的get請求獲得,下面使用urllib的post請求

    這裡通過http://httpbin.org/post網站演示(該網站可以作為練習使用urllib的一個站點使用,可以

    模擬各種請求操作)。

# urlopen傳入Request對象
b'name=WHY&localtion=SDU&language=Python'
# 直接傳入data
b'word=hello'
import urllib
name=WHY&location=SDU&language=Python

這裡就用到urllib.parse,通過bytes(urllib.parse.urlencode())可以將post數據進行轉換放到urllib.request.urlopendata參數中。這樣就完成了一次post請求。所以如果我們添加data參數的時候就是以post請求方式請求,如果沒有data參數就是get請求方式

  • timeout參數的使用

    在某些網絡情況不好或者服務器端異常的情況會出現請求慢的情況,或者請求異常,所以這個時候我們需要給

    請求設置一個超時時間,而不是讓程序一直在等待結果。例子如下:

import urllib.request
b'{\n "args": {}, \n "headers": {\n "Accept-Encoding": "identity", \n "Connection": "close", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.6"\n }, \n "origin": "218.75.27.189", \n "url": "http://httpbin.org/get"\n}\n'

我們需要對異常進行抓取,代碼更改為

import socket
TIME OUT

響應response

響應類型、狀態碼、響應頭

response.status、response.getheaders()、response.getheader("server"),獲取狀態碼以及頭部信息

response.read()獲得的是響應體的內容

import urllib.request
<class 'http.client.HTTPResponse'>

設置Headers

有很多網站為了防止程序爬蟲爬網站造成網站癱瘓,會需要攜帶一些headers頭部信息才能訪問,最常見的有user-agent參數

給請求添加頭部信息,從而定製自己請求網站是時的頭部信息

from urllib import request, parse
{

添加請求頭的第二種方式

這種添加方式有個好處是自己可以定義一個請求頭字典,然後循環進行添加

  • 實例化一個對象

  • 使用add_header方法添加Header

from urllib import request, parse
{

異常處理

在很多時候我們通過程序訪問頁面的時候,有的頁面可能會出現錯誤,類似404,500等錯誤

from urllib import request,error
Not Found

HTTPErrorURLError的子類

  • URLError裡只有一個屬性:reason,即抓異常的時候只能打印錯誤信息,類似上面的例子

  • HTTPError裡有三個屬性:code,reason,headers,即抓異常的時候可以獲得code,reson,headers三個信息

import urllib

捕獲異常

from urllib import request,error
Not Found
import urllib

e.reason其實也可以在做深入的判斷,例子如下:

import socket
<class 'socket.timeout'>
import http

pprint

Type: module
pprint.pprint(http.HTTPStatus.PARTIAL_CONTENT)
<HTTPStatus.PARTIAL_CONTENT: 206>

高級用法各種handler

代理,ProxyHandler

通過rulllib.request.ProxyHandler()可以設置代理,網站它會檢測某一段時間某個IP 的訪問次數,如果訪問次數過多,它會禁止你的訪問,所以這個時候需要通過設置代理來爬取數據

import urllib

cookie,HTTPCookiProcessor

cookie中保存中我們常見的登錄信息,有時候爬取網站需要攜帶cookie信息訪問,這裡用到了http.cookijar,用於獲取cookie以及存儲cookie

更多內容可查看python_cookie

import http.cookiejar, urllib.request
BAIDUID=FD7AB8ACCA2E3FFFCC647B0C8A4F90AE:FG=1

同時cookie可以寫入到文件中保存,有兩種方式http.cookiejar.MozillaCookieJar和http.cookiejar.LWPCookieJar()

# http.cookiejar.MozillaCookieJar()方式
# http.cookiejar.LWPCookieJar()方式

同樣的如果想要通過獲取文件中的cookie獲取的話可以通過load方式,當然用哪種方式寫入的,就用哪種方式讀取。

import http.cookiejar, urllib.request
<html>

urllib.request.urlretrieve

urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)

Retrieve a URL into a temporary location on disk.

參數

  • finename: 指定了保存本地路徑(如果參數未指定,urllib會生成一個臨時文件保存數據。)

  • reporthook: 是一個回調函數,當連接上服務器、以及相應的數據塊傳輸完畢時會觸發該回調,我們可以利用這個回調函數來顯示當前的下載進度。

  • data: 指 post 到服務器的數據,該方法返回一個包含兩個元素的(filename, headers)元組,filename 表示保存到本地的路徑,header 表示服務器的響應頭。

    http://images.china.cn/attachement/jpg/site1000/20160924/b8aeed99057d1950b64d04.jpg

    詳細內容參見網絡編程初探

# 下面是 urlretrieve() 下載文件實例,可以顯示下載進度
0.00%

URL解析

urlparse

urllib.parse.urlparse(url, scheme='', allow_fragments=True)

就是可以對你傳入的url地址進行拆分,同時我們是可以指定協議類型:

result = urlparse("www.baidu.com/index.html;user?id=5#comment",scheme="https")

這樣拆分的時候協議類型部分就會是你指定的部分,當然如果你的url裡面已經帶了協議,你再通過scheme指定的協議就不會生效

from urllib.parse import urlparse
ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')

urlunpars

其實功能和urlparse的功能相反,它是用於拼接,例子如下:

from urllib.parse import urlunparse
http://www.baidu.com/index.html;user?a=123#commit

urljoin

這個的功能其實是做拼接的(從拼接的結果我們可以看出,拼接的時候後面的優先級高於前面的url),例子如下:

from urllib.parse import urljoin
http://www.baidu.com/FAQ.html

urlencode

這個方法可以將字典轉換為url參數,例子如下

from urllib.parse import urlencode
http://www.baidu.com?name=zhaofan&age=23

一個簡單的爬蟲例子

import string,urllib
seed = 'http://yjsb.wzu.edu.cn/Art/Art_156/Art_156_913.aspx' # 最開始的種子

相關推薦

推薦中...