urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
還有 context 參數,它必須是 ssl.SSLContext 類型,用來指定 SSL 設置。
cafile 和 capath 兩個參數是指定 CA 證書和它的路徑,這個在請求 HTTPS 連接時會有用。
2- Request
urlopen() 方法能夠實現最基本請求的發起,但這幾個簡單的參數並不足以構建一個完整的請求,若是請求中須要加入 Headers 等信息
詳解Request
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
· headers參數是一個字典,Request Headers,經常使用於修改User-Agent來假裝瀏覽器如:
Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11
可直接設置,也能夠經過實例req add_header()來設置python
· method爲請求方法:get,post,put等
3- 高級用法
Handler 各類處理器,有專門處理登陸驗證的,有處理 Cookies 的,有處理代理設置的,利用它們咱們幾乎能夠作到任何 HTTP 請求中全部的事情。
大致流程
先根據需求,用不一樣方法,構建(設置)出不一樣處理器(handler)
而後利用handler構造一個opener = build_opener(xx_handler),以後發送請求
BaseHandler類,全部Handler的父類。提供了最基本的 Handler 的方法,例如 default_open()、protocol_request() 方法等。
OpenerDirector,咱們能夠稱之爲 Opener,相似於urlopen()
認證、代理、Cookies
3.1.2 處理異常
Urllib 的 error 模塊定義了由 request 模塊產生的異常
1- URLError
URLError 類來自 Urllib 庫的 error 模塊,它繼承自 OSError 類,是 error 異常模塊的基類,由 request 模塊生的異常均可以經過捕獲這個類來處理。
具備一個屬性reason
2- HttpError
它是 URLError 的子類,專門用來處理 HTTP 請求錯誤,好比認證請求失敗等等。
它有三個屬性。
· code,返回 HTTP Status Code,即狀態碼,好比 404 網頁不存在,500 服務器內部錯誤等等。
· reason,同父類同樣,返回錯誤的緣由。
· headers,返回 Request Headers。
由於 URLError 是 HTTPError 的父類,因此咱們能夠先選擇捕獲子類的錯誤,再去捕獲父類的錯誤,因此上述代碼更好的寫法以下:
from urllib import request, error
try:
response = request.urlopen('http://cuiqingcai.com/index.htm')
except error.HTTPError as e:
print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
print(e.reason)
else:
print('Request Successfully')
這樣咱們就能夠作到先捕獲 HTTPError,獲取它的錯誤狀態碼、緣由、Headers 等詳細信息。若是非 HTTPError,再捕獲 URLError 異常,輸出錯誤緣由。最後用 else 來處理正常的邏輯,這是一個較好的異常處理寫法。
3.1.3 解析連接
parse模塊,定義處理URL的標準接口。例如實現 URL 各部分的抽取,合併以及連接轉換。
1- urlparse() 解析網址
返回結果是一個 ParseResult 類型的對象,它包含了六個部分,分別是 scheme、netloc、path、params、query、fragment。
API:正則表達式
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
網址,協議,片斷
2- urlunparse() 構造
3- urlsplit()
和urlparse相似,返回一個元組
4- urlunsplit() 拼接
5- urljoin()
前面提到的urlunparse和unsplit等能夠連接合並,不過前提要有特定長度的對象
另一個辦法是利用 urljoin() 方法。咱們能夠提供一個 base_url(基礎連接),新的連接做爲第二個參數,方法會分析 base_url 的 scheme、netloc、path 這三個內容對新連接缺失的部分進行補充,做爲結果返回。
#更方便,易操做
6- urlencode()
將構造好的參數字典,轉化爲URL的參數
7- parse_qs()
和6對應,實現序列參數轉化成字典
8- parse_qsl()
參數轉化爲元組列表
9- quote()
將內容轉化爲 URL 編碼的格式
10- unquote() 還原
3.1.4 分析robots協議
利用 Urllib 的 robotparser 模塊咱們能夠實現網站 Robots 協議的分析
1- Robots協議
爬蟲協議,網絡爬蟲排除標準
用來告訴爬蟲和搜索引擎哪些頁面能夠抓取,哪些不能夠抓取。它一般是一個叫作 robots.txt 的文本文件,放在網站的根目錄下。
User-agent: *
Disallow: /
Allow: /public/
2- robotparser
使用RobotFileParser解析 robots.txt
urllib.robotparser.RobotFileParser(url='')
先建立一個robofileparser對象,而後經過set_url()方法設置 robots.txt連接。
下一步利用can_fetch()方法判斷王爺是否能夠被抓取
也能夠利用parser() 方法讀取和分析
3.2 Request
在前面一節咱們瞭解了 Urllib 的基本用法,可是其中確實有不方便的地方。好比處理網頁驗證、處理 Cookies 等等,須要寫 Opener、Handler 來進行處理。爲了更加方便地實現這些操做,在這裏就有了更爲強大的庫 Requests,有了它,Cookies、登陸驗證、代理設置等等操做簡單
3.2.1 基本使用
import requests
r = requests.get('https://www.baidu.com/')
print(type(r))
print(r.status_code)
print(type(r.text))
print(r.text)
print(r.cookies)
get() 方法便可實現和 urlopen() 相同的操做,獲得一個 Response 對象,而後分別輸出了 Response 的類型,Status Code,Response Body 的類型、內容還有 Cookies。
· GET請求
params 添加參數
調用r.json() 能夠將返回結果轉換爲字典格式
· POST請求
import requests
data = {'name': 'germey', 'age': '22'}
r = requests.post("http://httpbin.org/post", data=data)
print(r.text)
返回中,form部分就是提交的數據
· Response
發送 Request 以後,獲得的天然就是 Response,在上面的實例中咱們使用了 text 和 content 獲取了 Response 內容,不過還有不少屬性和方法能夠獲取其餘的信息,好比狀態碼 Status Code、Headers、Cookies 等信息。
statuscode 有好多,如200成功,404notfound
3.2.2 高級用法 (需重點掌握)
文件上傳,代理設置,Cookies 設置
1- 文件上傳
requests 設置files
2- Cookies設置
3- 會話維持
在 Requests 中,咱們若是直接利用 get() 或 post() 等方法的確能夠作到模擬網頁的請求。可是這其實是至關於不一樣的會話,即不一樣的 Session,也就是說至關於你用了兩個瀏覽器打開了不一樣的頁面。
requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')
->
s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
利用 Session 咱們能夠作到模擬同一個會話,並且不用擔憂 Cookies 的問題,一般用於模擬登陸成功以後再進行下一步的操做。
能夠用於模擬在一個瀏覽器中打開同一站點的不一樣頁面,
4- SSL證書驗證
Requests 提供了證書驗證的功能,當發送 HTTP 請求的時候,它會檢查 SSL 證書,咱們可使用 verify 這個參數來控制是否檢查此證書,其實若是不加的話默認是 True,會自動驗證。
5- 代理設置
某些網站大規模爬取是會封IP
request裏的proxies參數
6- 超時設置 timeout() 參數
7- 身份認證
8- Prepared Request**
在前面介紹 Urllib 時咱們能夠將 Request 表示爲一個數據結構,Request 的各個參數均可以經過一個 Request 對象來表示,在 Requests 裏面一樣能夠作到,這個數據結構就叫 Prepared Request。
from requests import Request, Session
url = 'http://httpbin.org/post'
data = {
'name': 'germey'
}
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
}
s = Session()
req = Request('POST', url, data=data, headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)
有了 Request 這個對象,咱們就能夠將一個個請求當作一個獨立的對象來看待,這樣在進行隊列調度的時候會很是方便。
3.3 正則表達式
3.3.1 基本使用
實現字符串的檢索、替換、匹配驗證
URL: [a-zA-z]+://[^\s]*

3.3.2- re庫
3.3.3- match() 開頭匹配
非貪婪策略不適用於字符串結尾內容的匹配
修飾符
遇到換行符,須要加在match()中,第三個參數re.S

總結:儘可能使用泛匹配;使用括號獲得匹配目標;儘可能使用非貪婪模式;有換行符就用re.S
3.3.4- search() 查詢匹配
match從頭開始查,不匹配返回none
result = re.search('<li.*?active.*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
print(result.group(1), result.group(2))
因爲絕大部分的 HTML 文本都包含了換行符,因此經過上面的例子,咱們儘可能都須要加上 re.S 修飾符,以避免出現匹配不到的問題。
爲了匹配方便,能用search就不用match
3.3.5- findall()
search() 能夠返回匹配正則表達式的第一個內容,但若是想得到匹配的全部內容,須要findall()
仍是上面的 HTML 文本,若是咱們想獲取全部 a 節點的超連接、歌手和歌名,就能夠將 search() 方法換成 findall() 方法。若是有返回結果的話就是列表類型,因此咱們須要遍歷一下來獲依次獲取每組內容。
3.3.6- sub() 修改文本
想獲取全部li節點全部歌名,直接正則比較麻煩,能夠先用sub把a節點去掉,只留下文本,再利用findall提取
html = re.sub('<a.*?>|</a>', '', html)
print(html)
results = re.findall('<li.*?>(.*?)</li>', html, re.S)
for result in results:
print(result.strip())
3.3.7-compile()
將字符串編譯成正則表達式對象
給正則表達式作了一層封裝,以便於咱們更好地複用。